0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <kunit/test.h>
0011 #include <linux/completion.h>
0012 #include <linux/kernel.h>
0013 #include <linux/kthread.h>
0014
0015 #include "try-catch-impl.h"
0016
0017 void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)
0018 {
0019 try_catch->try_result = -EFAULT;
0020 kthread_complete_and_exit(try_catch->try_completion, -EFAULT);
0021 }
0022 EXPORT_SYMBOL_GPL(kunit_try_catch_throw);
0023
0024 static int kunit_generic_run_threadfn_adapter(void *data)
0025 {
0026 struct kunit_try_catch *try_catch = data;
0027
0028 try_catch->try(try_catch->context);
0029
0030 kthread_complete_and_exit(try_catch->try_completion, 0);
0031 }
0032
0033 static unsigned long kunit_test_timeout(void)
0034 {
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 return 300 * msecs_to_jiffies(MSEC_PER_SEC);
0056 }
0057
0058 void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
0059 {
0060 DECLARE_COMPLETION_ONSTACK(try_completion);
0061 struct kunit *test = try_catch->test;
0062 struct task_struct *task_struct;
0063 int exit_code, time_remaining;
0064
0065 try_catch->context = context;
0066 try_catch->try_completion = &try_completion;
0067 try_catch->try_result = 0;
0068 task_struct = kthread_run(kunit_generic_run_threadfn_adapter,
0069 try_catch,
0070 "kunit_try_catch_thread");
0071 if (IS_ERR(task_struct)) {
0072 try_catch->catch(try_catch->context);
0073 return;
0074 }
0075
0076 time_remaining = wait_for_completion_timeout(&try_completion,
0077 kunit_test_timeout());
0078 if (time_remaining == 0) {
0079 kunit_err(test, "try timed out\n");
0080 try_catch->try_result = -ETIMEDOUT;
0081 kthread_stop(task_struct);
0082 }
0083
0084 exit_code = try_catch->try_result;
0085
0086 if (!exit_code)
0087 return;
0088
0089 if (exit_code == -EFAULT)
0090 try_catch->try_result = 0;
0091 else if (exit_code == -EINTR)
0092 kunit_err(test, "wake_up_process() was never called\n");
0093 else if (exit_code)
0094 kunit_err(test, "Unknown error: %d\n", exit_code);
0095
0096 try_catch->catch(try_catch->context);
0097 }
0098 EXPORT_SYMBOL_GPL(kunit_try_catch_run);