summaryrefslogtreecommitdiff
path: root/mali_kbase/tests/kutf/kutf_suite.c
diff options
context:
space:
mode:
Diffstat (limited to 'mali_kbase/tests/kutf/kutf_suite.c')
-rw-r--r--mali_kbase/tests/kutf/kutf_suite.c596
1 files changed, 209 insertions, 387 deletions
diff --git a/mali_kbase/tests/kutf/kutf_suite.c b/mali_kbase/tests/kutf/kutf_suite.c
index ad30cc8..4968f24 100644
--- a/mali_kbase/tests/kutf/kutf_suite.c
+++ b/mali_kbase/tests/kutf/kutf_suite.c
@@ -27,12 +27,14 @@
#include <linux/fs.h>
#include <linux/version.h>
#include <linux/atomic.h>
+#include <linux/sched.h>
#include <generated/autoconf.h>
#include <kutf/kutf_suite.h>
#include <kutf/kutf_resultset.h>
#include <kutf/kutf_utils.h>
+#include <kutf/kutf_helpers.h>
#if defined(CONFIG_DEBUG_FS)
@@ -61,8 +63,6 @@ struct kutf_application {
* @variant_list: List head to store all the variants which can run on
* this function
* @dir: debugfs directory for this test function
- * @userdata_ops: Callbacks to use for sending and receiving data to
- * userspace.
*/
struct kutf_test_function {
struct kutf_suite *suite;
@@ -73,7 +73,6 @@ struct kutf_test_function {
struct list_head node;
struct list_head variant_list;
struct dentry *dir;
- struct kutf_userdata_ops userdata_ops;
};
/**
@@ -83,17 +82,16 @@ struct kutf_test_function {
* @fixture_index: Index of this fixture
* @node: List node for variant_list
* @dir: debugfs directory for this test fixture
- * @nr_running: Current count of user-clients running this fixture
*/
struct kutf_test_fixture {
struct kutf_test_function *test_func;
unsigned int fixture_index;
struct list_head node;
struct dentry *dir;
- atomic_t nr_running;
};
-struct dentry *base_dir;
+static struct dentry *base_dir;
+static struct workqueue_struct *kutf_workq;
/**
* struct kutf_convert_table - Structure which keeps test results
@@ -252,263 +250,6 @@ static const struct file_operations kutf_debugfs_const_string_ops = {
};
/**
- * kutf_debugfs_data_open() Debugfs open callback for the "data" entry.
- * @inode: inode of the opened file
- * @file: Opened file to read from
- *
- * This function notifies the userdata callbacks that the userdata file has
- * been opened, for tracking purposes.
- *
- * It is called on both the context's userdata_consumer_priv and
- * userdata_producer_priv.
- *
- * This takes a refcount on the kutf_context
- *
- * Return: 0 on success
- */
-static int kutf_debugfs_data_open(struct inode *inode, struct file *file)
-{
- struct kutf_context *test_context = inode->i_private;
- struct kutf_test_fixture *test_fix = test_context->test_fix;
- struct kutf_test_function *test_func = test_fix->test_func;
- int err;
-
- simple_open(inode, file);
-
- /* This is not an error */
- if (!test_func->userdata_ops.open)
- goto out_no_ops;
-
- /* This is safe here - the 'data' file is only openable whilst the
- * initial refcount is still present, and the initial refcount is only
- * dropped strictly after the 'data' file is removed */
- kutf_context_get(test_context);
-
- if (test_context->userdata_consumer_priv) {
- err = test_func->userdata_ops.open(test_context->userdata_consumer_priv);
- if (err)
- goto out_consumer_fail;
- }
-
- if (test_context->userdata_producer_priv) {
- err = test_func->userdata_ops.open(test_context->userdata_producer_priv);
- if (err)
- goto out_producer_fail;
- }
-
-out_no_ops:
- return 0;
-
-out_producer_fail:
- if (test_func->userdata_ops.release && test_context->userdata_consumer_priv)
- test_func->userdata_ops.release(test_context->userdata_consumer_priv);
-out_consumer_fail:
- kutf_context_put(test_context);
-
- return err;
-}
-
-
-/**
- * kutf_debugfs_data_read() Debugfs read callback for the "data" entry.
- * @file: Opened file to read from
- * @buf: User buffer to write the data into
- * @len: Amount of data to read
- * @ppos: Offset into file to read from
- *
- * This function allows user and kernel to exchange extra data necessary for
- * the test fixture.
- *
- * The data is read from the first struct kutf_context running the fixture
- *
- * Return: Number of bytes read
- */
-static ssize_t kutf_debugfs_data_read(struct file *file, char __user *buf,
- size_t len, loff_t *ppos)
-{
- struct kutf_context *test_context = file->private_data;
- struct kutf_test_fixture *test_fix = test_context->test_fix;
- struct kutf_test_function *test_func = test_fix->test_func;
- ssize_t (*producer)(void *private, char __user *userbuf,
- size_t userbuf_len, loff_t *ppos);
- ssize_t count;
-
- producer = test_func->userdata_ops.producer;
- /* Can only read if there's a producer callback */
- if (!producer)
- return -ENODEV;
-
- count = producer(test_context->userdata_producer_priv, buf, len, ppos);
-
- return count;
-}
-
-/**
- * kutf_debugfs_data_write() Debugfs write callback for the "data" entry.
- * @file: Opened file to write to
- * @buf: User buffer to read the data from
- * @len: Amount of data to write
- * @ppos: Offset into file to write to
- *
- * This function allows user and kernel to exchange extra data necessary for
- * the test fixture.
- *
- * The data is added to the first struct kutf_context running the fixture
- *
- * Return: Number of bytes written
- */
-static ssize_t kutf_debugfs_data_write(struct file *file,
- const char __user *buf, size_t len, loff_t *ppos)
-{
- struct kutf_context *test_context = file->private_data;
- struct kutf_test_fixture *test_fix = test_context->test_fix;
- struct kutf_test_function *test_func = test_fix->test_func;
- ssize_t (*consumer)(void *private, const char __user *userbuf,
- size_t userbuf_len, loff_t *ppos);
- ssize_t count;
-
- consumer = test_func->userdata_ops.consumer;
- /* Can only write if there's a consumer callback */
- if (!consumer)
- return -ENODEV;
-
- count = consumer(test_context->userdata_consumer_priv, buf, len, ppos);
-
- return count;
-}
-
-
-/**
- * kutf_debugfs_data_release() - Debugfs release callback for the "data" entry.
- * @inode: File entry representation
- * @file: A specific opening of the file
- *
- * This function notifies the userdata callbacks that the userdata file has
- * been closed, for tracking purposes.
- *
- * It is called on both the context's userdata_consumer_priv and
- * userdata_producer_priv.
- *
- * It also drops the refcount on the kutf_context that was taken during
- * kutf_debugfs_data_open()
- */
-static int kutf_debugfs_data_release(struct inode *inode, struct file *file)
-{
- struct kutf_context *test_context = file->private_data;
- struct kutf_test_fixture *test_fix = test_context->test_fix;
- struct kutf_test_function *test_func = test_fix->test_func;
-
- if (!test_func->userdata_ops.release)
- return 0;
-
- if (test_context->userdata_consumer_priv)
- test_func->userdata_ops.release(test_context->userdata_consumer_priv);
- if (test_context->userdata_producer_priv)
- test_func->userdata_ops.release(test_context->userdata_producer_priv);
-
- kutf_context_put(test_context);
-
- return 0;
-}
-
-
-static const struct file_operations kutf_debugfs_data_ops = {
- .owner = THIS_MODULE,
- .open = kutf_debugfs_data_open,
- .read = kutf_debugfs_data_read,
- .write = kutf_debugfs_data_write,
- .release = kutf_debugfs_data_release,
- .llseek = default_llseek,
-};
-
-/**
- * userdata_init() - Initialize userspace data exchange for a test, if
- * specified by that test
- * @test_context: Test context
- *
- * Note that this allows new refcounts to be made on test_context by userspace
- * threads opening the 'data' file.
- *
- * Return: 0 on success, negative value corresponding to error code in failure
- * and kutf result will be set appropriately to indicate the error
- */
-static int userdata_init(struct kutf_context *test_context)
-{
- struct kutf_test_fixture *test_fix = test_context->test_fix;
- struct kutf_test_function *test_func = test_fix->test_func;
- int err = 0;
- struct dentry *userdata_dentry;
-
- /* Valid to have neither a producer or consumer, which is the case for
- * tests not requiring usersdata */
- if ((!test_func->userdata_ops.consumer) && (!test_func->userdata_ops.producer))
- return err;
-
- if (test_func->userdata_ops.consumer && !test_context->userdata_consumer_priv) {
- kutf_test_fatal(test_context,
- "incorrect test setup - userdata consumer provided without private data");
- return -EFAULT;
- }
-
- if (test_func->userdata_ops.producer && !test_context->userdata_producer_priv) {
- kutf_test_fatal(test_context,
- "incorrect test setup - userdata producer provided without private data");
- return -EFAULT;
- }
-
- userdata_dentry = debugfs_create_file("data", S_IROTH, test_fix->dir,
- test_context, &kutf_debugfs_data_ops);
-
- if (!userdata_dentry) {
- pr_err("Failed to create debugfs file \"data\" when running fixture\n");
- /* Not using Fatal (which stops other tests running),
- * nor Abort (which indicates teardown should not be done) */
- kutf_test_fail(test_context,
- "failed to create 'data' file for userside data exchange");
-
- /* Error code is discarded by caller, but consistent with other
- * debugfs_create_file failures */
- err = -EEXIST;
- } else {
- test_context->userdata_dentry = userdata_dentry;
- }
-
-
- return err;
-}
-
-/**
- * userdata_term() - Terminate userspace data exchange for a test, if specified
- * by that test
- * @test_context: Test context
- *
- * Note This also prevents new refcounts being made on @test_context by userspace
- * threads opening the 'data' file for this test. Any existing open file descriptors
- * to the 'data' file will still be safe to use by userspace.
- */
-static void userdata_term(struct kutf_context *test_context)
-{
- struct kutf_test_fixture *test_fix = test_context->test_fix;
- struct kutf_test_function *test_func = test_fix->test_func;
- void (*notify_ended)(void *priv) = test_func->userdata_ops.notify_ended;
-
- /* debugfs_remove() is safe when parameter is error or NULL */
- debugfs_remove(test_context->userdata_dentry);
-
- /* debugfs_remove() doesn't kill any currently open file descriptors on
- * this file, and such fds are still safe to use providing test_context
- * is properly refcounted */
-
- if (notify_ended) {
- if (test_context->userdata_consumer_priv)
- notify_ended(test_context->userdata_consumer_priv);
- if (test_context->userdata_producer_priv)
- notify_ended(test_context->userdata_producer_priv);
- }
-
-}
-
-/**
* kutf_add_explicit_result() - Check if an explicit result needs to be added
* @context: KUTF test context
*/
@@ -563,75 +304,75 @@ static void kutf_add_explicit_result(struct kutf_context *context)
}
}
+static void kutf_run_test(struct work_struct *data)
+{
+ struct kutf_context *test_context = container_of(data,
+ struct kutf_context, work);
+ struct kutf_suite *suite = test_context->suite;
+ struct kutf_test_function *test_func;
+
+ test_func = test_context->test_fix->test_func;
+
+ /*
+ * Call the create fixture function if required before the
+ * fixture is run
+ */
+ if (suite->create_fixture)
+ test_context->fixture = suite->create_fixture(test_context);
+
+ /* Only run the test if the fixture was created (if required) */
+ if ((suite->create_fixture && test_context->fixture) ||
+ (!suite->create_fixture)) {
+ /* Run this fixture */
+ test_func->execute(test_context);
+
+ if (suite->remove_fixture)
+ suite->remove_fixture(test_context);
+
+ kutf_add_explicit_result(test_context);
+ }
+
+ kutf_add_result(test_context, KUTF_RESULT_TEST_FINISHED, NULL);
+
+ kutf_context_put(test_context);
+}
+
/**
* kutf_debugfs_run_open() Debugfs open callback for the "run" entry.
* @inode: inode of the opened file
* @file: Opened file to read from
*
- * This function retrieves the test fixture data that is associated with the
- * opened file and works back to get the test, suite and application so
- * it can then run the test that is associated with the file entry.
+ * This function creates a KUTF context and queues it onto a workqueue to be
+ * run asynchronously. The resulting file descriptor can be used to communicate
+ * userdata to the test and to read back the results of the test execution.
*
* Return: 0 on success
*/
static int kutf_debugfs_run_open(struct inode *inode, struct file *file)
{
struct kutf_test_fixture *test_fix = inode->i_private;
- struct kutf_test_function *test_func = test_fix->test_func;
- struct kutf_suite *suite = test_func->suite;
struct kutf_context *test_context;
int err = 0;
- /* For the moment, only one user-client should be attempting to run
- * this at a time. This simplifies how we lookup the kutf_context when
- * using the 'data' file.
- * Removing this restriction would require a rewrite of the mechanism
- * of the 'data' file to pass data in, perhaps 'data' created here and
- * based upon userspace thread's pid */
- if (atomic_inc_return(&test_fix->nr_running) != 1) {
- err = -EBUSY;
- goto finish;
- }
-
test_context = kutf_create_context(test_fix);
if (!test_context) {
- err = -ENODEV;
+ err = -ENOMEM;
goto finish;
}
file->private_data = test_context;
- /*
- * Call the create fixture function if required before the
- * fixture is run
- */
- if (suite->create_fixture)
- test_context->fixture = suite->create_fixture(test_context);
-
- /* Only run the test if the fixture was created (if required) */
- if ((suite->create_fixture && test_context->fixture) ||
- (!suite->create_fixture)) {
- int late_err;
- /* Setup any userdata exchange */
- late_err = userdata_init(test_context);
-
- if (!late_err)
- /* Run this fixture */
- test_func->execute(test_context);
-
- userdata_term(test_context);
-
- if (suite->remove_fixture)
- suite->remove_fixture(test_context);
+ /* This reference is release by the kutf_run_test */
+ kutf_context_get(test_context);
- kutf_add_explicit_result(test_context);
- }
+ queue_work(kutf_workq, &test_context->work);
finish:
- atomic_dec(&test_fix->nr_running);
return err;
}
+#define USERDATA_WARNING_MESSAGE "WARNING: This test requires userdata\n"
+
/**
* kutf_debugfs_run_read() - Debugfs read callback for the "run" entry.
* @file: Opened file to read from
@@ -639,8 +380,14 @@ finish:
* @len: Amount of data to read
* @ppos: Offset into file to read from
*
- * This function emits the results which where logged during the opening of
- * the file kutf_debugfs_run_open.
+ * This function emits the results of the test, blocking until they are
+ * available.
+ *
+ * If the test involves user data then this will also return user data records
+ * to user space. If the test is waiting for user data then this function will
+ * output a message (to make the likes of 'cat' display it), followed by
+ * returning 0 to mark the end of file.
+ *
* Results will be emitted one at a time, once all the results have been read
* 0 will be returned to indicate there is no more data.
*
@@ -653,68 +400,153 @@ static ssize_t kutf_debugfs_run_read(struct file *file, char __user *buf,
struct kutf_result *res;
unsigned long bytes_not_copied;
ssize_t bytes_copied = 0;
+ char *kutf_str_ptr = NULL;
+ size_t kutf_str_len = 0;
+ size_t message_len = 0;
+ char separator = ':';
+ char terminator = '\n';
- /* Note: This code assumes a result is read completely */
res = kutf_remove_result(test_context->result_set);
- if (res) {
- char *kutf_str_ptr = NULL;
- unsigned int kutf_str_len = 0;
- unsigned int message_len = 0;
- char separator = ':';
- char terminator = '\n';
-
- kutf_result_to_string(&kutf_str_ptr, res->status);
- if (kutf_str_ptr)
- kutf_str_len = strlen(kutf_str_ptr);
-
- if (res->message)
- message_len = strlen(res->message);
-
- if ((kutf_str_len + 1 + message_len + 1) > len) {
- pr_err("Not enough space in user buffer for a single result");
+
+ if (IS_ERR(res))
+ return PTR_ERR(res);
+
+ /*
+ * Handle 'fake' results - these results are converted to another
+ * form before being returned from the kernel
+ */
+ switch (res->status) {
+ case KUTF_RESULT_TEST_FINISHED:
+ return 0;
+ case KUTF_RESULT_USERDATA_WAIT:
+ if (test_context->userdata.flags &
+ KUTF_USERDATA_WARNING_OUTPUT) {
+ /*
+ * Warning message already output,
+ * signal end-of-file
+ */
return 0;
}
- /* First copy the result string */
- if (kutf_str_ptr) {
- bytes_not_copied = copy_to_user(&buf[0], kutf_str_ptr,
- kutf_str_len);
- bytes_copied += kutf_str_len - bytes_not_copied;
- if (bytes_not_copied)
- goto exit;
+ message_len = sizeof(USERDATA_WARNING_MESSAGE)-1;
+ if (message_len > len)
+ message_len = len;
+
+ bytes_not_copied = copy_to_user(buf,
+ USERDATA_WARNING_MESSAGE,
+ message_len);
+ if (bytes_not_copied != 0)
+ return -EFAULT;
+ test_context->userdata.flags |= KUTF_USERDATA_WARNING_OUTPUT;
+ return message_len;
+ case KUTF_RESULT_USERDATA:
+ message_len = strlen(res->message);
+ if (message_len > len-1) {
+ message_len = len-1;
+ pr_warn("User data truncated, read not long enough\n");
+ }
+ bytes_not_copied = copy_to_user(buf, res->message,
+ message_len);
+ if (bytes_not_copied != 0) {
+ pr_warn("Failed to copy data to user space buffer\n");
+ return -EFAULT;
+ }
+ /* Finally the terminator */
+ bytes_not_copied = copy_to_user(&buf[message_len],
+ &terminator, 1);
+ if (bytes_not_copied != 0) {
+ pr_warn("Failed to copy data to user space buffer\n");
+ return -EFAULT;
}
+ return message_len+1;
+ default:
+ /* Fall through - this is a test result */
+ break;
+ }
- /* Then the separator */
- bytes_not_copied = copy_to_user(&buf[bytes_copied],
- &separator, 1);
- bytes_copied += 1 - bytes_not_copied;
+ /* Note: This code assumes a result is read completely */
+ kutf_result_to_string(&kutf_str_ptr, res->status);
+ if (kutf_str_ptr)
+ kutf_str_len = strlen(kutf_str_ptr);
+
+ if (res->message)
+ message_len = strlen(res->message);
+
+ if ((kutf_str_len + 1 + message_len + 1) > len) {
+ pr_err("Not enough space in user buffer for a single result");
+ return 0;
+ }
+
+ /* First copy the result string */
+ if (kutf_str_ptr) {
+ bytes_not_copied = copy_to_user(&buf[0], kutf_str_ptr,
+ kutf_str_len);
+ bytes_copied += kutf_str_len - bytes_not_copied;
if (bytes_not_copied)
goto exit;
+ }
- /* Finally Next copy the result string */
- if (res->message) {
- bytes_not_copied = copy_to_user(&buf[bytes_copied],
- res->message, message_len);
- bytes_copied += message_len - bytes_not_copied;
- if (bytes_not_copied)
- goto exit;
- }
+ /* Then the separator */
+ bytes_not_copied = copy_to_user(&buf[bytes_copied],
+ &separator, 1);
+ bytes_copied += 1 - bytes_not_copied;
+ if (bytes_not_copied)
+ goto exit;
- /* Finally the terminator */
+ /* Finally Next copy the result string */
+ if (res->message) {
bytes_not_copied = copy_to_user(&buf[bytes_copied],
- &terminator, 1);
- bytes_copied += 1 - bytes_not_copied;
+ res->message, message_len);
+ bytes_copied += message_len - bytes_not_copied;
+ if (bytes_not_copied)
+ goto exit;
}
+
+ /* Finally the terminator */
+ bytes_not_copied = copy_to_user(&buf[bytes_copied],
+ &terminator, 1);
+ bytes_copied += 1 - bytes_not_copied;
+
exit:
return bytes_copied;
}
/**
+ * kutf_debugfs_run_write() Debugfs write callback for the "run" entry.
+ * @file: Opened file to write to
+ * @buf: User buffer to read the data from
+ * @len: Amount of data to write
+ * @ppos: Offset into file to write to
+ *
+ * This function allows user and kernel to exchange extra data necessary for
+ * the test fixture.
+ *
+ * The data is added to the first struct kutf_context running the fixture
+ *
+ * Return: Number of bytes written
+ */
+static ssize_t kutf_debugfs_run_write(struct file *file,
+ const char __user *buf, size_t len, loff_t *ppos)
+{
+ int ret = 0;
+ struct kutf_context *test_context = file->private_data;
+
+ if (len > KUTF_MAX_LINE_LENGTH)
+ return -EINVAL;
+
+ ret = kutf_helper_input_enqueue(test_context, buf, len);
+ if (ret < 0)
+ return ret;
+
+ return len;
+}
+
+/**
* kutf_debugfs_run_release() - Debugfs release callback for the "run" entry.
* @inode: File entry representation
* @file: A specific opening of the file
*
- * Release any resources that where created during the opening of the file
+ * Release any resources that were created during the opening of the file
*
* Note that resources may not be released immediately, that might only happen
* later when other users of the kutf_context release their refcount.
@@ -725,6 +557,8 @@ static int kutf_debugfs_run_release(struct inode *inode, struct file *file)
{
struct kutf_context *test_context = file->private_data;
+ kutf_helper_input_enqueue_end_of_data(test_context);
+
kutf_context_put(test_context);
return 0;
}
@@ -733,6 +567,7 @@ static const struct file_operations kutf_debugfs_run_ops = {
.owner = THIS_MODULE,
.open = kutf_debugfs_run_open,
.read = kutf_debugfs_run_read,
+ .write = kutf_debugfs_run_write,
.release = kutf_debugfs_run_release,
.llseek = default_llseek,
};
@@ -763,7 +598,6 @@ static int create_fixture_variant(struct kutf_test_function *test_func,
test_fix->test_func = test_func;
test_fix->fixture_index = fixture_index;
- atomic_set(&test_fix->nr_running, 0);
snprintf(name, sizeof(name), "%d", fixture_index);
test_fix->dir = debugfs_create_dir(name, test_func->dir);
@@ -783,8 +617,14 @@ static int create_fixture_variant(struct kutf_test_function *test_func,
goto fail_file;
}
- tmp = debugfs_create_file("run", S_IROTH, test_fix->dir, test_fix,
- &kutf_debugfs_run_ops);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
+ tmp = debugfs_create_file_unsafe(
+#else
+ tmp = debugfs_create_file(
+#endif
+ "run", 0600, test_fix->dir,
+ test_fix,
+ &kutf_debugfs_run_ops);
if (!tmp) {
pr_err("Failed to create debugfs file \"run\" when adding fixture\n");
/* Might not be the right error, we don't get it passed back to us */
@@ -813,14 +653,13 @@ static void kutf_remove_test_variant(struct kutf_test_fixture *test_fix)
kfree(test_fix);
}
-void kutf_add_test_with_filters_data_and_userdata(
+void kutf_add_test_with_filters_and_data(
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)
+ union kutf_callback_data test_data)
{
struct kutf_test_function *test_func;
struct dentry *tmp;
@@ -873,7 +712,6 @@ void kutf_add_test_with_filters_data_and_userdata(
test_func->suite = suite;
test_func->execute = execute;
test_func->test_data = test_data;
- memcpy(&test_func->userdata_ops, userdata_ops, sizeof(*userdata_ops));
list_add(&test_func->node, &suite->test_list);
return;
@@ -885,27 +723,6 @@ fail_dir:
fail_alloc:
return;
}
-EXPORT_SYMBOL(kutf_add_test_with_filters_data_and_userdata);
-
-void kutf_add_test_with_filters_and_data(
- 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 = {
- .open = NULL,
- .release = NULL,
- .consumer = NULL,
- .producer = NULL,
- };
-
- kutf_add_test_with_filters_data_and_userdata(suite, id, name, execute,
- filters, test_data, &userdata_ops);
-}
-
EXPORT_SYMBOL(kutf_add_test_with_filters_and_data);
void kutf_add_test_with_filters(
@@ -1150,7 +967,7 @@ static struct kutf_context *kutf_create_context(
new_context->result_set = kutf_create_result_set();
if (!new_context->result_set) {
- pr_err("Failed to create resultset");
+ pr_err("Failed to create result set");
goto fail_result_set;
}
@@ -1165,9 +982,12 @@ static struct kutf_context *kutf_create_context(
new_context->fixture_index = test_fix->fixture_index;
new_context->fixture_name = NULL;
new_context->test_data = test_fix->test_func->test_data;
- new_context->userdata_consumer_priv = NULL;
- new_context->userdata_producer_priv = NULL;
- new_context->userdata_dentry = NULL;
+
+ new_context->userdata.flags = 0;
+ INIT_LIST_HEAD(&new_context->userdata.input_head);
+ init_waitqueue_head(&new_context->userdata.input_waitq);
+
+ INIT_WORK(&new_context->work, kutf_run_test);
kref_init(&new_context->kref);
@@ -1227,8 +1047,7 @@ static void kutf_test_log_result(
context->status = new_status;
if (context->expected_status != new_status)
- kutf_add_result(&context->fixture_pool, context->result_set,
- new_status, message);
+ kutf_add_result(context, new_status, message);
}
void kutf_test_log_result_external(
@@ -1344,18 +1163,18 @@ EXPORT_SYMBOL(kutf_test_abort);
*/
static int __init init_kutf_core(void)
{
- int ret;
+ kutf_workq = alloc_workqueue("kutf workq", WQ_UNBOUND, 1);
+ if (!kutf_workq)
+ return -ENOMEM;
base_dir = debugfs_create_dir("kutf_tests", NULL);
if (!base_dir) {
- ret = -ENODEV;
- goto exit_dir;
+ destroy_workqueue(kutf_workq);
+ kutf_workq = NULL;
+ return -ENOMEM;
}
return 0;
-
-exit_dir:
- return ret;
}
/**
@@ -1366,6 +1185,9 @@ exit_dir:
static void __exit exit_kutf_core(void)
{
debugfs_remove_recursive(base_dir);
+
+ if (kutf_workq)
+ destroy_workqueue(kutf_workq);
}
#else /* defined(CONFIG_DEBUG_FS) */