diff options
author | Sidath Senanayake <sidaths@google.com> | 2017-11-08 13:23:34 +0100 |
---|---|---|
committer | Sidath Senanayake <sidaths@google.com> | 2017-11-08 13:23:34 +0100 |
commit | dbd2655766535ffc24e24503a7279f3abfd40d7e (patch) | |
tree | 87f651aaa936267783d365eab5502d24f6be2d14 /mali_kbase/tests/include | |
parent | c19c62718d90e8efa4675528aae6ab6fde13a12f (diff) | |
download | gpu-dbd2655766535ffc24e24503a7279f3abfd40d7e.tar.gz |
Mali Bifrost DDK r9p0 KMD
Provenance:
b336f554d (collaborate/EAC/b_r9p0)
BX304L01B-BU-00000-r9p0-01rel0
BX304L06A-BU-00000-r9p0-01rel0
BX304X07X-BU-00000-r9p0-01rel0
Signed-off-by: Sidath Senanayake <sidaths@google.com>
Change-Id: Iaff4ad1413fa7d768d5d250afadbb24d19e1e2e2
Diffstat (limited to 'mali_kbase/tests/include')
-rw-r--r-- | mali_kbase/tests/include/kutf/kutf_helpers.h | 202 | ||||
-rw-r--r-- | mali_kbase/tests/include/kutf/kutf_helpers_user.h | 49 | ||||
-rw-r--r-- | mali_kbase/tests/include/kutf/kutf_resultset.h | 77 | ||||
-rw-r--r-- | mali_kbase/tests/include/kutf/kutf_suite.h | 98 |
4 files changed, 164 insertions, 262 deletions
diff --git a/mali_kbase/tests/include/kutf/kutf_helpers.h b/mali_kbase/tests/include/kutf/kutf_helpers.h index 3f1dfc2..3667687 100644 --- a/mali_kbase/tests/include/kutf/kutf_helpers.h +++ b/mali_kbase/tests/include/kutf/kutf_helpers.h @@ -21,196 +21,52 @@ /* kutf_helpers.h * Test helper functions for the kernel UTF test infrastructure. * - * This collection of helper functions are provided as 'stock' implementation - * helpers for certain features of kutf. Tests can implement common/boilerplate - * functionality using these, whilst still providing them the option of - * implementing completely custom functions themselves to use those kutf - * features. + * These functions provide methods for enqueuing/dequeuing lines of text sent + * by user space. They are used to implement the transfer of "userdata" from + * user space to kernel. */ #include <kutf/kutf_suite.h> -#include <kutf/kutf_mem.h> -#include <linux/wait.h> /** - * enum kutf_helper_textbuf_flag - flags for textbufs - * @KUTF_HELPER_TEXTBUF_FLAG_DYING: Test is dying, textbuf should not allow - * writes, nor block on empty. - */ -enum kutf_helper_textbuf_flag { - KUTF_HELPER_TEXTBUF_FLAG_DYING = (1u << 0), -}; - -/** - * struct kutf_helper_textbuf_line - Structure representing a line of text + * kutf_helper_input_dequeue() - Dequeue a line sent by user space + * @context: KUTF context + * @str_size: Pointer to an integer to receive the size of the string * - * The string itself is stored immediately after this. + * If no line is available then this function will wait (interruptibly) until + * a line is available. * - * @node: List node for the textbuf's textbuf_list - * @str_size: Length of the string buffer, including the \0 terminator - * @str: 'Flexible array' for the string representing the line + * Return: The line dequeued, ERR_PTR(-EINTR) if interrupted or NULL on end + * of data. */ -struct kutf_helper_textbuf_line { - struct list_head node; - int str_size; - char str[]; -}; - -/** - * struct kutf_helper_textbuf - Structure to representing sequential lines of - * text - * @lock: mutex to hold whilst accessing the structure - * @nr_user_clients: Number of userspace clients connected via an open() - * call - * @mempool: mempool for allocating lines - * @scratchpad: scratch area for receiving text of size max_line_size - * @used_bytes: number of valid bytes in the scratchpad - * @prev_pos: Previous position userspace has accessed - * @prev_line_pos: Previous start of line position userspace has accessed - * @textbuf_list: List head to store all the lines of text - * @max_line_size: Maximum size in memory allowed for a line of text - * @max_nr_lines: Maximum number of lines permitted in this textbuf - * @nr_lines: Number of entries in textbuf_list - * @flags: Flags indicating state of the textbuf, using values - * from enum kutf_helper_textbuf_flag - * @user_opened_wq: Waitq for when there's at least one userspace client - * connected to the textbuf via an open() call - * @not_full_wq: Waitq for when the textbuf can be enqueued into/can - * consume data from userspace - * @not_empty_wq: Waitq for when the textbuf can be dequeued from/can - * produce data for userspace - */ - -struct kutf_helper_textbuf { - struct mutex lock; - int nr_user_clients; - struct kutf_mempool *mempool; - char *scratchpad; - int used_bytes; - loff_t prev_pos; - loff_t prev_line_pos; - struct list_head textbuf_list; - int max_line_size; - int max_nr_lines; - int nr_lines; - unsigned long flags; - wait_queue_head_t user_opened_wq; - wait_queue_head_t not_full_wq; - wait_queue_head_t not_empty_wq; - -}; - -/* stock callbacks for userspace to read from/write to the 'data' file as a - * textbuf */ -extern struct kutf_userdata_ops kutf_helper_textbuf_userdata_ops; +char *kutf_helper_input_dequeue(struct kutf_context *context, size_t *str_size); /** - * kutf_helper_textbuf_init() - init a textbuf for use as a 'data' file - * consumer/producer - * @textbuf: textbuf to initialize - * @mempool: mempool to allocate from - * @max_line_size: maximum line size expected to/from userspace - * @max_nr_lines: maximum number of lines to expect to/from userspace + * kutf_helper_input_enqueue() - Enqueue a line sent by user space + * @context: KUTF context + * @str: The user space address of the line + * @size: The length in bytes of the string * - * Initialize a textbuf so that it can consume writes made to the 'data' file, - * and produce reads for userspace on the 'data' file. Tests may then read the - * lines written by userspace, or fill the buffer so it may be read back by - * userspace. + * This function will use copy_from_user to copy the string out of user space. + * The string need not be NULL-terminated (@size should not include the NULL + * termination). * - * The caller should write the @textbuf pointer into the kutf_context's - * userdata_producer_priv or userdata_consumer_priv member during fixture - * creation. + * As a special case @str==NULL and @size==0 is valid to mark the end of input, + * but callers should use kutf_helper_input_enqueue_end_of_data() instead. * - * Usually a test will have separate textbufs for userspace to write to and - * read from. Using the same one for both will echo back to the user what they - * are writing. - * - * Lines are understood as being separated by the '\n' character, but no '\n' - * characters will be observed by the test - * - * @max_line_size puts an upper bound on the size of lines in a textbuf, - * including the \0 terminator. Lines exceeding this will be truncated, - * effectively ignoring incoming data until the next '\n' - * - * Combining this with @max_nr_lines puts an upper bound on the size of the - * file read in - * - * Return: 0 on success, or negative value on error. + * Return: 0 on success, -EFAULT if the line cannot be copied from user space, + * -ENOMEM if out of memory. */ -int kutf_helper_textbuf_init(struct kutf_helper_textbuf *textbuf, - struct kutf_mempool *mempool, int max_line_size, - int max_nr_lines); +int kutf_helper_input_enqueue(struct kutf_context *context, + const char __user *str, size_t size); /** - * kutf_helper_textbuf_wait_for_user() - wait for userspace to open the 'data' - * file - * @textbuf: textbuf to wait on - * - * This can be used to synchronize with userspace so that subsequent calls to - * kutf_helper_textbuf_dequeue() and kutf_helper_textbuf_enqueue() should - * succeed. - * - * Waiting is done on a timeout. - * - * There is of course no guarantee that userspace will keep the file open after - * this, but any error in the dequeue/enqueue functions afterwards can be - * treated as such rather than "we're still waiting for userspace to begin" - * - * Return: 0 if waited successfully, -ETIMEDOUT if we exceeded the - * timeout, or some other negative value if there was an - * error during waiting. - */ - -int kutf_helper_textbuf_wait_for_user(struct kutf_helper_textbuf *textbuf); - - -/** - * kutf_helper_textbuf_dequeue() - dequeue a line from a textbuf - * @textbuf: textbuf dequeue a line as a string from - * @str_size: pointer to storage to receive the size of the string, - * which includes the '\0' terminator, or NULL if not - * required - * - * Dequeue (remove) a line from the start of the textbuf as a string, and - * return it. - * - * If no lines are available, then this will block until a line has been - * submitted. If a userspace client is not connected and there are no remaining - * lines, then this function returns NULL instead. - * - * The memory for the string comes from the kutf_mempool given during - * initialization of the textbuf, and shares the same lifetime as it. - * - * Return: pointer to the next line of the textbuf. NULL indicated - * all userspace clients disconnected. An error value to be - * checked with IS_ERR() family of functions if a signal or - * some other error occurred - */ -char *kutf_helper_textbuf_dequeue(struct kutf_helper_textbuf *textbuf, - int *str_size); - -/** - * kutf_helper_textbuf_enqueue() - enqueue a line to a textbuf - * @textbuf: textbuf to enqueue a line as a string to - * @enqueue_str: pointer to the string to enqueue to the textbuf - * @buf_max_size: maximum size of the buffer holding @enqueue_str - * - * Enqueue (add) a line to the end of a textbuf as a string. - * - * The caller should avoid placing '\n' characters in their strings, as these - * will not be split into multiple lines. - * - * A copy of the string will be made into the textbuf, so @enqueue_str can be - * freed immediately after if.the caller wishes to do so. - * - * If the maximum amount of lines has been reached, then this will block until - * a line has been removed to make space. If a userspace client is not - * connected and there is no space available, then this function returns - * -EBUSY. + * kutf_helper_input_enqueue_end_of_data() - Signal no more data is to be sent + * @context: KUTF context * - * Return: 0 on success, or negative value on error + * After this function has been called, kutf_helper_input_dequeue() will always + * return NULL. */ -int kutf_helper_textbuf_enqueue(struct kutf_helper_textbuf *textbuf, - char *enqueue_str, int buf_max_size); +void kutf_helper_input_enqueue_end_of_data(struct kutf_context *context); #endif /* _KERNEL_UTF_HELPERS_H_ */ diff --git a/mali_kbase/tests/include/kutf/kutf_helpers_user.h b/mali_kbase/tests/include/kutf/kutf_helpers_user.h index 759bf71..c7b5263 100644 --- a/mali_kbase/tests/include/kutf/kutf_helpers_user.h +++ b/mali_kbase/tests/include/kutf/kutf_helpers_user.h @@ -80,18 +80,16 @@ enum kutf_helper_err { }; -/* textbuf Send named NAME=value pair, u64 value +/* Send named NAME=value pair, u64 value * * NAME must match [A-Z0-9_]\+ and can be up to MAX_VAL_NAME_LEN characters long * - * This is assuming the kernel-side test is using the 'textbuf' helpers - * * Any failure will be logged on the suite's current test fixture * * Returns 0 on success, non-zero on failure */ -int kutf_helper_textbuf_send_named_u64(struct kutf_context *context, - struct kutf_helper_textbuf *textbuf, char *val_name, u64 val); +int kutf_helper_send_named_u64(struct kutf_context *context, + const char *val_name, u64 val); /* Get the maximum length of a string that can be represented as a particular * NAME="value" pair without string-value truncation in the kernel's buffer @@ -101,53 +99,48 @@ int kutf_helper_textbuf_send_named_u64(struct kutf_context *context, * without having the string value truncated. Any string longer than this will * be truncated at some point during communication to this size. * - * The calculation is valid both for sending strings of val_str_len to kernel, - * and for receiving a string that was originally val_str_len from the kernel. - * - * It is assumed that valname is a valid name for - * kutf_test_helpers_textbuf_send_named_str(), and no checking will be made to + * It is assumed that val_name is a valid name for + * kutf_helper_send_named_str(), and no checking will be made to * ensure this. * * Returns the maximum string length that can be represented, or a negative * value if the NAME="value" encoding itself wouldn't fit in kern_buf_sz */ -int kutf_helper_textbuf_max_str_len_for_kern(char *val_name, int kern_buf_sz); +int kutf_helper_max_str_len_for_kern(const char *val_name, int kern_buf_sz); -/* textbuf Send named NAME="str" pair +/* Send named NAME="str" pair * * no escaping allowed in str. Any of the following characters will terminate * the string: '"' '\\' '\n' * * NAME must match [A-Z0-9_]\+ and can be up to MAX_VAL_NAME_LEN characters long * - * This is assuming the kernel-side test is using the 'textbuf' helpers - * * Any failure will be logged on the suite's current test fixture * * Returns 0 on success, non-zero on failure */ -int kutf_helper_textbuf_send_named_str(struct kutf_context *context, - struct kutf_helper_textbuf *textbuf, char *val_name, - char *val_str); +int kutf_helper_send_named_str(struct kutf_context *context, + const char *val_name, const char *val_str); -/* textbuf Receive named NAME=value pair +/* Receive named NAME=value pair * * This can receive u64 and string values - check named_val->type * * If you are not planning on dynamic handling of the named value's name and - * type, then kutf_test_helpers_textbuf_receive_check_val() is more useful as a + * type, then kutf_helper_receive_check_val() is more useful as a * convenience function. * * String members of named_val will come from memory allocated on the fixture's mempool * - * Returns 0 on success. Negative value on failure to receive from the 'data' + * Returns 0 on success. Negative value on failure to receive from the 'run' * file, positive value indicates an enum kutf_helper_err value for correct * reception of data but invalid parsing */ -int kutf_helper_textbuf_receive_named_val(struct kutf_helper_named_val *named_val, - struct kutf_helper_textbuf *textbuf); +int kutf_helper_receive_named_val( + struct kutf_context *context, + struct kutf_helper_named_val *named_val); -/* textbuf Receive and validate NAME=value pair +/* Receive and validate NAME=value pair * - * As with kutf_test_helpers_textbuf_receive_named_val, but validate that the + * As with kutf_helper_receive_named_val, but validate that the * name and type are as expected, as a convenience for a common pattern found * in tests. * @@ -168,9 +161,11 @@ int kutf_helper_textbuf_receive_named_val(struct kutf_helper_named_val *named_va * * The rationale behind this is that we'd prefer to continue the rest of the * test with failures propagated, rather than hitting a timeout */ -int kutf_helper_textbuf_receive_check_val(struct kutf_helper_named_val *named_val, - struct kutf_context *context, struct kutf_helper_textbuf *textbuf, - char *expect_val_name, enum kutf_helper_valtype expect_val_type); +int kutf_helper_receive_check_val( + struct kutf_helper_named_val *named_val, + struct kutf_context *context, + const char *expect_val_name, + enum kutf_helper_valtype expect_val_type); /* Output a named value to kmsg */ void kutf_helper_output_named_val(struct kutf_helper_named_val *named_val); diff --git a/mali_kbase/tests/include/kutf/kutf_resultset.h b/mali_kbase/tests/include/kutf/kutf_resultset.h index 1cc85f1..6787f71 100644 --- a/mali_kbase/tests/include/kutf/kutf_resultset.h +++ b/mali_kbase/tests/include/kutf/kutf_resultset.h @@ -42,7 +42,12 @@ * @KUTF_RESULT_FATAL: The test result failed with a fatal error. * @KUTF_RESULT_ABORT: The test result failed due to a non-UTF * assertion failure. - * @KUTF_RESULT_COUNT: The current number of possible status messages. + * @KUTF_RESULT_USERDATA: User data is ready to be read, + * this is not seen outside the kernel + * @KUTF_RESULT_USERDATA_WAIT: Waiting for user data to be sent, + * this is not seen outside the kernel + * @KUTF_RESULT_TEST_FINISHED: The test has finished, no more results will + * be produced. This is not seen outside kutf */ enum kutf_result_status { KUTF_RESULT_BENCHMARK = -3, @@ -57,7 +62,9 @@ enum kutf_result_status { KUTF_RESULT_FATAL = 5, KUTF_RESULT_ABORT = 6, - KUTF_RESULT_COUNT + KUTF_RESULT_USERDATA = 7, + KUTF_RESULT_USERDATA_WAIT = 8, + KUTF_RESULT_TEST_FINISHED = 9 }; /* The maximum size of a kutf_result_status result when @@ -68,6 +75,9 @@ enum kutf_result_status { #ifdef __KERNEL__ #include <kutf/kutf_mem.h> +#include <linux/wait.h> + +struct kutf_context; /** * struct kutf_result - Represents a single test result. @@ -82,40 +92,85 @@ struct kutf_result { }; /** + * KUTF_RESULT_SET_WAITING_FOR_INPUT - Test is waiting for user data + * + * This flag is set within a struct kutf_result_set whenever the test is blocked + * waiting for user data. Attempts to dequeue results when this flag is set + * will cause a dummy %KUTF_RESULT_USERDATA_WAIT result to be produced. This + * is used to output a warning message and end of file. + */ +#define KUTF_RESULT_SET_WAITING_FOR_INPUT 1 + +/** + * struct kutf_result_set - Represents a set of results. + * @results: List head of a struct kutf_result list for storing the results + * @waitq: Wait queue signalled whenever new results are added. + * @flags: Flags see %KUTF_RESULT_SET_WAITING_FOR_INPUT + */ +struct kutf_result_set { + struct list_head results; + wait_queue_head_t waitq; + int flags; +}; + +/** * kutf_create_result_set() - Create a new result set * to which results can be added. * - * Return: The created resultset. + * Return: The created result set. */ struct kutf_result_set *kutf_create_result_set(void); /** - * kutf_add_result() - Add a result to the end of an existing resultset. + * kutf_add_result() - Add a result to the end of an existing result set. * - * @mempool: The memory pool to allocate the result storage from. - * @set: The resultset to add the result to. + * @context: The kutf context * @status: The result status to add. * @message: The result message to add. + * + * Return: 0 if the result is successfully added. -ENOMEM if allocation fails. */ -void kutf_add_result(struct kutf_mempool *mempool, struct kutf_result_set *set, +int kutf_add_result(struct kutf_context *context, enum kutf_result_status status, const char *message); /** - * kutf_remove_result() - Remove a result from the head of a resultset. - * @set: The resultset. + * kutf_remove_result() - Remove a result from the head of a result set. + * @set: The result set. + * + * This function will block until there is a result to read. The wait is + * interruptible, so this function will return with an ERR_PTR if interrupted. * - * Return: result or NULL if there are no further results in the resultset. + * Return: result or ERR_PTR if interrupted */ struct kutf_result *kutf_remove_result( struct kutf_result_set *set); /** - * kutf_destroy_result_set() - Free a previously created resultset. + * kutf_destroy_result_set() - Free a previously created result set. * * @results: The result set whose resources to free. */ void kutf_destroy_result_set(struct kutf_result_set *results); +/** + * kutf_set_waiting_for_input() - The test is waiting for userdata + * + * @set: The result set to update + * + * Causes the result set to always have results and return a fake + * %KUTF_RESULT_USERDATA_WAIT result. + */ +void kutf_set_waiting_for_input(struct kutf_result_set *set); + +/** + * kutf_clear_waiting_for_input() - The test is no longer waiting for userdata + * + * @set: The result set to update + * + * Cancels the effect of kutf_set_waiting_for_input() + */ +void kutf_clear_waiting_for_input(struct kutf_result_set *set); + #endif /* __KERNEL__ */ #endif /* _KERNEL_UTF_RESULTSET_H_ */ diff --git a/mali_kbase/tests/include/kutf/kutf_suite.h b/mali_kbase/tests/include/kutf/kutf_suite.h index cba2b2d..ca30e57 100644 --- a/mali_kbase/tests/include/kutf/kutf_suite.h +++ b/mali_kbase/tests/include/kutf/kutf_suite.h @@ -27,10 +27,17 @@ */ #include <linux/kref.h> +#include <linux/workqueue.h> +#include <linux/wait.h> #include <kutf/kutf_mem.h> #include <kutf/kutf_resultset.h> +/* Arbitrary maximum size to prevent user space allocating too much kernel + * memory + */ +#define KUTF_MAX_LINE_LENGTH (1024u) + /** * Pseudo-flag indicating an absence of any specified test class. Note that * tests should not be annotated with this constant as it is simply a zero @@ -149,24 +156,42 @@ union kutf_callback_data { }; /** - * struct kutf_userdata_ops- Structure defining methods to exchange data - * with userspace via the 'data' file - * @open: Function used to notify when the 'data' file was opened - * @release: Function used to notify when the 'data' file was closed - * @notify_ended: Function used to notify when the test has ended. - * @consumer: Function used to consume writes from userspace - * @producer: Function used to produce data for userspace to read + * struct kutf_userdata_line - A line of user data to be returned to the user + * @node: struct list_head to link this into a list + * @str: The line of user data to return to user space + * @size: The number of bytes within @str + */ +struct kutf_userdata_line { + struct list_head node; + char *str; + size_t size; +}; + +/** + * KUTF_USERDATA_WARNING_OUTPUT - Flag specifying that a warning has been output * - * All ops can be NULL. - */ -struct kutf_userdata_ops { - int (*open)(void *priv); - void (*release)(void *priv); - void (*notify_ended)(void *priv); - ssize_t (*consumer)(void *priv, const char __user *userbuf, - size_t userbuf_len, loff_t *ppos); - ssize_t (*producer)(void *priv, char __user *userbuf, - size_t userbuf_len, loff_t *ppos); + * If user space reads the "run" file while the test is waiting for user data, + * then the framework will output a warning message and set this flag within + * struct kutf_userdata. A subsequent read will then simply return an end of + * file condition rather than outputting the warning again. The upshot of this + * is that simply running 'cat' on a test which requires user data will produce + * the warning followed by 'cat' exiting due to EOF - which is much more user + * friendly than blocking indefinitely waiting for user data. + */ +#define KUTF_USERDATA_WARNING_OUTPUT 1 + +/** + * struct kutf_userdata - Structure holding user data + * @flags: See %KUTF_USERDATA_WARNING_OUTPUT + * @input_head: List of struct kutf_userdata_line containing user data + * to be read by the kernel space test. + * @input_waitq: Wait queue signalled when there is new user data to be + * read by the kernel space test. + */ +struct kutf_userdata { + unsigned long flags; + struct list_head input_head; + wait_queue_head_t input_waitq; }; /** @@ -185,13 +210,8 @@ struct kutf_userdata_ops { * @status: The status of the currently running fixture. * @expected_status: The expected status on exist of the currently * running fixture. - * @userdata_consumer_priv: Parameter to pass into kutf_userdata_ops - * consumer function. Must not be NULL if a - * consumer function was specified - * @userdata_producer_priv: Parameter to pass into kutf_userdata_ops - * producer function. Must not be NULL if a - * producer function was specified - * @userdata_dentry: The debugfs file for userdata exchange + * @work: Work item to enqueue onto the work queue to run the test + * @userdata: Structure containing the user data for the test to read */ struct kutf_context { struct kref kref; @@ -205,9 +225,9 @@ struct kutf_context { struct kutf_result_set *result_set; enum kutf_result_status status; enum kutf_result_status expected_status; - void *userdata_consumer_priv; - void *userdata_producer_priv; - struct dentry *userdata_dentry; + + struct work_struct work; + struct kutf_userdata userdata; }; /** @@ -391,30 +411,6 @@ void kutf_add_test_with_filters_and_data( unsigned int filters, union kutf_callback_data test_data); -/** - * kutf_add_test_with_filters_data_and_userdata() - Add a test to a kernel test suite with filters and setup for - * receiving data from userside - * @suite: The suite to add the test to. - * @id: The ID of the test. - * @name: The name of the test. - * @execute: Callback to the test function to run. - * @filters: A set of filtering flags, assigning test categories. - * @test_data: Test specific callback data, provided during the - * running of the test in the kutf_context - * @userdata_ops: Callbacks to use for sending and receiving data to - * userspace. A copy of the struct kutf_userdata_ops is - * taken. Each callback can be NULL. - * - */ -void kutf_add_test_with_filters_data_and_userdata( - struct kutf_suite *suite, - unsigned int id, - const char *name, - void (*execute)(struct kutf_context *context), - unsigned int filters, - union kutf_callback_data test_data, - struct kutf_userdata_ops *userdata_ops); - /* ============================================================================ Test functions |