]> Git Repo - linux.git/blob - lib/kunit/test.c
mm/mmap: remove __vma_adjust()
[linux.git] / lib / kunit / test.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Base unit test (KUnit) API.
4  *
5  * Copyright (C) 2019, Google LLC.
6  * Author: Brendan Higgins <[email protected]>
7  */
8
9 #include <kunit/resource.h>
10 #include <kunit/test.h>
11 #include <kunit/test-bug.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15 #include <linux/panic.h>
16 #include <linux/sched/debug.h>
17 #include <linux/sched.h>
18
19 #include "debugfs.h"
20 #include "string-stream.h"
21 #include "try-catch-impl.h"
22
23 DEFINE_STATIC_KEY_FALSE(kunit_running);
24
25 #if IS_BUILTIN(CONFIG_KUNIT)
26 /*
27  * Fail the current test and print an error message to the log.
28  */
29 void __kunit_fail_current_test(const char *file, int line, const char *fmt, ...)
30 {
31         va_list args;
32         int len;
33         char *buffer;
34
35         if (!current->kunit_test)
36                 return;
37
38         kunit_set_failure(current->kunit_test);
39
40         /* kunit_err() only accepts literals, so evaluate the args first. */
41         va_start(args, fmt);
42         len = vsnprintf(NULL, 0, fmt, args) + 1;
43         va_end(args);
44
45         buffer = kunit_kmalloc(current->kunit_test, len, GFP_KERNEL);
46         if (!buffer)
47                 return;
48
49         va_start(args, fmt);
50         vsnprintf(buffer, len, fmt, args);
51         va_end(args);
52
53         kunit_err(current->kunit_test, "%s:%d: %s", file, line, buffer);
54         kunit_kfree(current->kunit_test, buffer);
55 }
56 EXPORT_SYMBOL_GPL(__kunit_fail_current_test);
57 #endif
58
59 /*
60  * Enable KUnit tests to run.
61  */
62 #ifdef CONFIG_KUNIT_DEFAULT_ENABLED
63 static bool enable_param = true;
64 #else
65 static bool enable_param;
66 #endif
67 module_param_named(enable, enable_param, bool, 0);
68 MODULE_PARM_DESC(enable, "Enable KUnit tests");
69
70 /*
71  * KUnit statistic mode:
72  * 0 - disabled
73  * 1 - only when there is more than one subtest
74  * 2 - enabled
75  */
76 static int kunit_stats_enabled = 1;
77 module_param_named(stats_enabled, kunit_stats_enabled, int, 0644);
78 MODULE_PARM_DESC(stats_enabled,
79                   "Print test stats: never (0), only for multiple subtests (1), or always (2)");
80
81 struct kunit_result_stats {
82         unsigned long passed;
83         unsigned long skipped;
84         unsigned long failed;
85         unsigned long total;
86 };
87
88 static bool kunit_should_print_stats(struct kunit_result_stats stats)
89 {
90         if (kunit_stats_enabled == 0)
91                 return false;
92
93         if (kunit_stats_enabled == 2)
94                 return true;
95
96         return (stats.total > 1);
97 }
98
99 static void kunit_print_test_stats(struct kunit *test,
100                                    struct kunit_result_stats stats)
101 {
102         if (!kunit_should_print_stats(stats))
103                 return;
104
105         kunit_log(KERN_INFO, test,
106                   KUNIT_SUBTEST_INDENT
107                   "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
108                   test->name,
109                   stats.passed,
110                   stats.failed,
111                   stats.skipped,
112                   stats.total);
113 }
114
115 /*
116  * Append formatted message to log, size of which is limited to
117  * KUNIT_LOG_SIZE bytes (including null terminating byte).
118  */
119 void kunit_log_append(char *log, const char *fmt, ...)
120 {
121         char line[KUNIT_LOG_SIZE];
122         va_list args;
123         int len_left;
124
125         if (!log)
126                 return;
127
128         len_left = KUNIT_LOG_SIZE - strlen(log) - 1;
129         if (len_left <= 0)
130                 return;
131
132         va_start(args, fmt);
133         vsnprintf(line, sizeof(line), fmt, args);
134         va_end(args);
135
136         strncat(log, line, len_left);
137 }
138 EXPORT_SYMBOL_GPL(kunit_log_append);
139
140 size_t kunit_suite_num_test_cases(struct kunit_suite *suite)
141 {
142         struct kunit_case *test_case;
143         size_t len = 0;
144
145         kunit_suite_for_each_test_case(suite, test_case)
146                 len++;
147
148         return len;
149 }
150 EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);
151
152 static void kunit_print_suite_start(struct kunit_suite *suite)
153 {
154         kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "KTAP version 1\n");
155         kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "# Subtest: %s",
156                   suite->name);
157         kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "1..%zd",
158                   kunit_suite_num_test_cases(suite));
159 }
160
161 static void kunit_print_ok_not_ok(void *test_or_suite,
162                                   bool is_test,
163                                   enum kunit_status status,
164                                   size_t test_number,
165                                   const char *description,
166                                   const char *directive)
167 {
168         struct kunit_suite *suite = is_test ? NULL : test_or_suite;
169         struct kunit *test = is_test ? test_or_suite : NULL;
170         const char *directive_header = (status == KUNIT_SKIPPED) ? " # SKIP " : "";
171
172         /*
173          * We do not log the test suite results as doing so would
174          * mean debugfs display would consist of the test suite
175          * description and status prior to individual test results.
176          * Hence directly printk the suite status, and we will
177          * separately seq_printf() the suite status for the debugfs
178          * representation.
179          */
180         if (suite)
181                 pr_info("%s %zd %s%s%s\n",
182                         kunit_status_to_ok_not_ok(status),
183                         test_number, description, directive_header,
184                         (status == KUNIT_SKIPPED) ? directive : "");
185         else
186                 kunit_log(KERN_INFO, test,
187                           KUNIT_SUBTEST_INDENT "%s %zd %s%s%s",
188                           kunit_status_to_ok_not_ok(status),
189                           test_number, description, directive_header,
190                           (status == KUNIT_SKIPPED) ? directive : "");
191 }
192
193 enum kunit_status kunit_suite_has_succeeded(struct kunit_suite *suite)
194 {
195         const struct kunit_case *test_case;
196         enum kunit_status status = KUNIT_SKIPPED;
197
198         if (suite->suite_init_err)
199                 return KUNIT_FAILURE;
200
201         kunit_suite_for_each_test_case(suite, test_case) {
202                 if (test_case->status == KUNIT_FAILURE)
203                         return KUNIT_FAILURE;
204                 else if (test_case->status == KUNIT_SUCCESS)
205                         status = KUNIT_SUCCESS;
206         }
207
208         return status;
209 }
210 EXPORT_SYMBOL_GPL(kunit_suite_has_succeeded);
211
212 static size_t kunit_suite_counter = 1;
213
214 static void kunit_print_suite_end(struct kunit_suite *suite)
215 {
216         kunit_print_ok_not_ok((void *)suite, false,
217                               kunit_suite_has_succeeded(suite),
218                               kunit_suite_counter++,
219                               suite->name,
220                               suite->status_comment);
221 }
222
223 unsigned int kunit_test_case_num(struct kunit_suite *suite,
224                                  struct kunit_case *test_case)
225 {
226         struct kunit_case *tc;
227         unsigned int i = 1;
228
229         kunit_suite_for_each_test_case(suite, tc) {
230                 if (tc == test_case)
231                         return i;
232                 i++;
233         }
234
235         return 0;
236 }
237 EXPORT_SYMBOL_GPL(kunit_test_case_num);
238
239 static void kunit_print_string_stream(struct kunit *test,
240                                       struct string_stream *stream)
241 {
242         struct string_stream_fragment *fragment;
243         char *buf;
244
245         if (string_stream_is_empty(stream))
246                 return;
247
248         buf = string_stream_get_string(stream);
249         if (!buf) {
250                 kunit_err(test,
251                           "Could not allocate buffer, dumping stream:\n");
252                 list_for_each_entry(fragment, &stream->fragments, node) {
253                         kunit_err(test, "%s", fragment->fragment);
254                 }
255                 kunit_err(test, "\n");
256         } else {
257                 kunit_err(test, "%s", buf);
258                 kunit_kfree(test, buf);
259         }
260 }
261
262 static void kunit_fail(struct kunit *test, const struct kunit_loc *loc,
263                        enum kunit_assert_type type, const struct kunit_assert *assert,
264                        assert_format_t assert_format, const struct va_format *message)
265 {
266         struct string_stream *stream;
267
268         kunit_set_failure(test);
269
270         stream = alloc_string_stream(test, GFP_KERNEL);
271         if (IS_ERR(stream)) {
272                 WARN(true,
273                      "Could not allocate stream to print failed assertion in %s:%d\n",
274                      loc->file,
275                      loc->line);
276                 return;
277         }
278
279         kunit_assert_prologue(loc, type, stream);
280         assert_format(assert, message, stream);
281
282         kunit_print_string_stream(test, stream);
283
284         string_stream_destroy(stream);
285 }
286
287 static void __noreturn kunit_abort(struct kunit *test)
288 {
289         kunit_try_catch_throw(&test->try_catch); /* Does not return. */
290
291         /*
292          * Throw could not abort from test.
293          *
294          * XXX: we should never reach this line! As kunit_try_catch_throw is
295          * marked __noreturn.
296          */
297         WARN_ONCE(true, "Throw could not abort from test!\n");
298 }
299
300 void kunit_do_failed_assertion(struct kunit *test,
301                                const struct kunit_loc *loc,
302                                enum kunit_assert_type type,
303                                const struct kunit_assert *assert,
304                                assert_format_t assert_format,
305                                const char *fmt, ...)
306 {
307         va_list args;
308         struct va_format message;
309         va_start(args, fmt);
310
311         message.fmt = fmt;
312         message.va = &args;
313
314         kunit_fail(test, loc, type, assert, assert_format, &message);
315
316         va_end(args);
317
318         if (type == KUNIT_ASSERTION)
319                 kunit_abort(test);
320 }
321 EXPORT_SYMBOL_GPL(kunit_do_failed_assertion);
322
323 void kunit_init_test(struct kunit *test, const char *name, char *log)
324 {
325         spin_lock_init(&test->lock);
326         INIT_LIST_HEAD(&test->resources);
327         test->name = name;
328         test->log = log;
329         if (test->log)
330                 test->log[0] = '\0';
331         test->status = KUNIT_SUCCESS;
332         test->status_comment[0] = '\0';
333 }
334 EXPORT_SYMBOL_GPL(kunit_init_test);
335
336 /*
337  * Initializes and runs test case. Does not clean up or do post validations.
338  */
339 static void kunit_run_case_internal(struct kunit *test,
340                                     struct kunit_suite *suite,
341                                     struct kunit_case *test_case)
342 {
343         if (suite->init) {
344                 int ret;
345
346                 ret = suite->init(test);
347                 if (ret) {
348                         kunit_err(test, "failed to initialize: %d\n", ret);
349                         kunit_set_failure(test);
350                         return;
351                 }
352         }
353
354         test_case->run_case(test);
355 }
356
357 static void kunit_case_internal_cleanup(struct kunit *test)
358 {
359         kunit_cleanup(test);
360 }
361
362 /*
363  * Performs post validations and cleanup after a test case was run.
364  * XXX: Should ONLY BE CALLED AFTER kunit_run_case_internal!
365  */
366 static void kunit_run_case_cleanup(struct kunit *test,
367                                    struct kunit_suite *suite)
368 {
369         if (suite->exit)
370                 suite->exit(test);
371
372         kunit_case_internal_cleanup(test);
373 }
374
375 struct kunit_try_catch_context {
376         struct kunit *test;
377         struct kunit_suite *suite;
378         struct kunit_case *test_case;
379 };
380
381 static void kunit_try_run_case(void *data)
382 {
383         struct kunit_try_catch_context *ctx = data;
384         struct kunit *test = ctx->test;
385         struct kunit_suite *suite = ctx->suite;
386         struct kunit_case *test_case = ctx->test_case;
387
388         current->kunit_test = test;
389
390         /*
391          * kunit_run_case_internal may encounter a fatal error; if it does,
392          * abort will be called, this thread will exit, and finally the parent
393          * thread will resume control and handle any necessary clean up.
394          */
395         kunit_run_case_internal(test, suite, test_case);
396         /* This line may never be reached. */
397         kunit_run_case_cleanup(test, suite);
398 }
399
400 static void kunit_catch_run_case(void *data)
401 {
402         struct kunit_try_catch_context *ctx = data;
403         struct kunit *test = ctx->test;
404         struct kunit_suite *suite = ctx->suite;
405         int try_exit_code = kunit_try_catch_get_result(&test->try_catch);
406
407         if (try_exit_code) {
408                 kunit_set_failure(test);
409                 /*
410                  * Test case could not finish, we have no idea what state it is
411                  * in, so don't do clean up.
412                  */
413                 if (try_exit_code == -ETIMEDOUT) {
414                         kunit_err(test, "test case timed out\n");
415                 /*
416                  * Unknown internal error occurred preventing test case from
417                  * running, so there is nothing to clean up.
418                  */
419                 } else {
420                         kunit_err(test, "internal error occurred preventing test case from running: %d\n",
421                                   try_exit_code);
422                 }
423                 return;
424         }
425
426         /*
427          * Test case was run, but aborted. It is the test case's business as to
428          * whether it failed or not, we just need to clean up.
429          */
430         kunit_run_case_cleanup(test, suite);
431 }
432
433 /*
434  * Performs all logic to run a test case. It also catches most errors that
435  * occur in a test case and reports them as failures.
436  */
437 static void kunit_run_case_catch_errors(struct kunit_suite *suite,
438                                         struct kunit_case *test_case,
439                                         struct kunit *test)
440 {
441         struct kunit_try_catch_context context;
442         struct kunit_try_catch *try_catch;
443
444         kunit_init_test(test, test_case->name, test_case->log);
445         try_catch = &test->try_catch;
446
447         kunit_try_catch_init(try_catch,
448                              test,
449                              kunit_try_run_case,
450                              kunit_catch_run_case);
451         context.test = test;
452         context.suite = suite;
453         context.test_case = test_case;
454         kunit_try_catch_run(try_catch, &context);
455
456         /* Propagate the parameter result to the test case. */
457         if (test->status == KUNIT_FAILURE)
458                 test_case->status = KUNIT_FAILURE;
459         else if (test_case->status != KUNIT_FAILURE && test->status == KUNIT_SUCCESS)
460                 test_case->status = KUNIT_SUCCESS;
461 }
462
463 static void kunit_print_suite_stats(struct kunit_suite *suite,
464                                     struct kunit_result_stats suite_stats,
465                                     struct kunit_result_stats param_stats)
466 {
467         if (kunit_should_print_stats(suite_stats)) {
468                 kunit_log(KERN_INFO, suite,
469                           "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
470                           suite->name,
471                           suite_stats.passed,
472                           suite_stats.failed,
473                           suite_stats.skipped,
474                           suite_stats.total);
475         }
476
477         if (kunit_should_print_stats(param_stats)) {
478                 kunit_log(KERN_INFO, suite,
479                           "# Totals: pass:%lu fail:%lu skip:%lu total:%lu",
480                           param_stats.passed,
481                           param_stats.failed,
482                           param_stats.skipped,
483                           param_stats.total);
484         }
485 }
486
487 static void kunit_update_stats(struct kunit_result_stats *stats,
488                                enum kunit_status status)
489 {
490         switch (status) {
491         case KUNIT_SUCCESS:
492                 stats->passed++;
493                 break;
494         case KUNIT_SKIPPED:
495                 stats->skipped++;
496                 break;
497         case KUNIT_FAILURE:
498                 stats->failed++;
499                 break;
500         }
501
502         stats->total++;
503 }
504
505 static void kunit_accumulate_stats(struct kunit_result_stats *total,
506                                    struct kunit_result_stats add)
507 {
508         total->passed += add.passed;
509         total->skipped += add.skipped;
510         total->failed += add.failed;
511         total->total += add.total;
512 }
513
514 int kunit_run_tests(struct kunit_suite *suite)
515 {
516         char param_desc[KUNIT_PARAM_DESC_SIZE];
517         struct kunit_case *test_case;
518         struct kunit_result_stats suite_stats = { 0 };
519         struct kunit_result_stats total_stats = { 0 };
520
521         /* Taint the kernel so we know we've run tests. */
522         add_taint(TAINT_TEST, LOCKDEP_STILL_OK);
523
524         if (suite->suite_init) {
525                 suite->suite_init_err = suite->suite_init(suite);
526                 if (suite->suite_init_err) {
527                         kunit_err(suite, KUNIT_SUBTEST_INDENT
528                                   "# failed to initialize (%d)", suite->suite_init_err);
529                         goto suite_end;
530                 }
531         }
532
533         kunit_print_suite_start(suite);
534
535         kunit_suite_for_each_test_case(suite, test_case) {
536                 struct kunit test = { .param_value = NULL, .param_index = 0 };
537                 struct kunit_result_stats param_stats = { 0 };
538                 test_case->status = KUNIT_SKIPPED;
539
540                 if (!test_case->generate_params) {
541                         /* Non-parameterised test. */
542                         kunit_run_case_catch_errors(suite, test_case, &test);
543                         kunit_update_stats(&param_stats, test.status);
544                 } else {
545                         /* Get initial param. */
546                         param_desc[0] = '\0';
547                         test.param_value = test_case->generate_params(NULL, param_desc);
548                         kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
549                                   "KTAP version 1\n");
550                         kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
551                                   "# Subtest: %s", test_case->name);
552
553                         while (test.param_value) {
554                                 kunit_run_case_catch_errors(suite, test_case, &test);
555
556                                 if (param_desc[0] == '\0') {
557                                         snprintf(param_desc, sizeof(param_desc),
558                                                  "param-%d", test.param_index);
559                                 }
560
561                                 kunit_log(KERN_INFO, &test,
562                                           KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
563                                           "%s %d %s",
564                                           kunit_status_to_ok_not_ok(test.status),
565                                           test.param_index + 1, param_desc);
566
567                                 /* Get next param. */
568                                 param_desc[0] = '\0';
569                                 test.param_value = test_case->generate_params(test.param_value, param_desc);
570                                 test.param_index++;
571
572                                 kunit_update_stats(&param_stats, test.status);
573                         }
574                 }
575
576
577                 kunit_print_test_stats(&test, param_stats);
578
579                 kunit_print_ok_not_ok(&test, true, test_case->status,
580                                       kunit_test_case_num(suite, test_case),
581                                       test_case->name,
582                                       test.status_comment);
583
584                 kunit_update_stats(&suite_stats, test_case->status);
585                 kunit_accumulate_stats(&total_stats, param_stats);
586         }
587
588         if (suite->suite_exit)
589                 suite->suite_exit(suite);
590
591         kunit_print_suite_stats(suite, suite_stats, total_stats);
592 suite_end:
593         kunit_print_suite_end(suite);
594
595         return 0;
596 }
597 EXPORT_SYMBOL_GPL(kunit_run_tests);
598
599 static void kunit_init_suite(struct kunit_suite *suite)
600 {
601         kunit_debugfs_create_suite(suite);
602         suite->status_comment[0] = '\0';
603         suite->suite_init_err = 0;
604 }
605
606 bool kunit_enabled(void)
607 {
608         return enable_param;
609 }
610
611 int __kunit_test_suites_init(struct kunit_suite * const * const suites, int num_suites)
612 {
613         unsigned int i;
614
615         if (!kunit_enabled() && num_suites > 0) {
616                 pr_info("kunit: disabled\n");
617                 return 0;
618         }
619
620         static_branch_inc(&kunit_running);
621
622         for (i = 0; i < num_suites; i++) {
623                 kunit_init_suite(suites[i]);
624                 kunit_run_tests(suites[i]);
625         }
626
627         static_branch_dec(&kunit_running);
628         return 0;
629 }
630 EXPORT_SYMBOL_GPL(__kunit_test_suites_init);
631
632 static void kunit_exit_suite(struct kunit_suite *suite)
633 {
634         kunit_debugfs_destroy_suite(suite);
635 }
636
637 void __kunit_test_suites_exit(struct kunit_suite **suites, int num_suites)
638 {
639         unsigned int i;
640
641         if (!kunit_enabled())
642                 return;
643
644         for (i = 0; i < num_suites; i++)
645                 kunit_exit_suite(suites[i]);
646
647         kunit_suite_counter = 1;
648 }
649 EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);
650
651 #ifdef CONFIG_MODULES
652 static void kunit_module_init(struct module *mod)
653 {
654         __kunit_test_suites_init(mod->kunit_suites, mod->num_kunit_suites);
655 }
656
657 static void kunit_module_exit(struct module *mod)
658 {
659         __kunit_test_suites_exit(mod->kunit_suites, mod->num_kunit_suites);
660 }
661
662 static int kunit_module_notify(struct notifier_block *nb, unsigned long val,
663                                void *data)
664 {
665         struct module *mod = data;
666
667         switch (val) {
668         case MODULE_STATE_LIVE:
669                 kunit_module_init(mod);
670                 break;
671         case MODULE_STATE_GOING:
672                 kunit_module_exit(mod);
673                 break;
674         case MODULE_STATE_COMING:
675         case MODULE_STATE_UNFORMED:
676                 break;
677         }
678
679         return 0;
680 }
681
682 static struct notifier_block kunit_mod_nb = {
683         .notifier_call = kunit_module_notify,
684         .priority = 0,
685 };
686 #endif
687
688 struct kunit_kmalloc_array_params {
689         size_t n;
690         size_t size;
691         gfp_t gfp;
692 };
693
694 static int kunit_kmalloc_array_init(struct kunit_resource *res, void *context)
695 {
696         struct kunit_kmalloc_array_params *params = context;
697
698         res->data = kmalloc_array(params->n, params->size, params->gfp);
699         if (!res->data)
700                 return -ENOMEM;
701
702         return 0;
703 }
704
705 static void kunit_kmalloc_array_free(struct kunit_resource *res)
706 {
707         kfree(res->data);
708 }
709
710 void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp)
711 {
712         struct kunit_kmalloc_array_params params = {
713                 .size = size,
714                 .n = n,
715                 .gfp = gfp
716         };
717
718         return kunit_alloc_resource(test,
719                                     kunit_kmalloc_array_init,
720                                     kunit_kmalloc_array_free,
721                                     gfp,
722                                     &params);
723 }
724 EXPORT_SYMBOL_GPL(kunit_kmalloc_array);
725
726 static inline bool kunit_kfree_match(struct kunit *test,
727                                      struct kunit_resource *res, void *match_data)
728 {
729         /* Only match resources allocated with kunit_kmalloc() and friends. */
730         return res->free == kunit_kmalloc_array_free && res->data == match_data;
731 }
732
733 void kunit_kfree(struct kunit *test, const void *ptr)
734 {
735         if (!ptr)
736                 return;
737
738         if (kunit_destroy_resource(test, kunit_kfree_match, (void *)ptr))
739                 KUNIT_FAIL(test, "kunit_kfree: %px already freed or not allocated by kunit", ptr);
740 }
741 EXPORT_SYMBOL_GPL(kunit_kfree);
742
743 void kunit_cleanup(struct kunit *test)
744 {
745         struct kunit_resource *res;
746         unsigned long flags;
747
748         /*
749          * test->resources is a stack - each allocation must be freed in the
750          * reverse order from which it was added since one resource may depend
751          * on another for its entire lifetime.
752          * Also, we cannot use the normal list_for_each constructs, even the
753          * safe ones because *arbitrary* nodes may be deleted when
754          * kunit_resource_free is called; the list_for_each_safe variants only
755          * protect against the current node being deleted, not the next.
756          */
757         while (true) {
758                 spin_lock_irqsave(&test->lock, flags);
759                 if (list_empty(&test->resources)) {
760                         spin_unlock_irqrestore(&test->lock, flags);
761                         break;
762                 }
763                 res = list_last_entry(&test->resources,
764                                       struct kunit_resource,
765                                       node);
766                 /*
767                  * Need to unlock here as a resource may remove another
768                  * resource, and this can't happen if the test->lock
769                  * is held.
770                  */
771                 spin_unlock_irqrestore(&test->lock, flags);
772                 kunit_remove_resource(test, res);
773         }
774         current->kunit_test = NULL;
775 }
776 EXPORT_SYMBOL_GPL(kunit_cleanup);
777
778 static int __init kunit_init(void)
779 {
780         kunit_debugfs_init();
781 #ifdef CONFIG_MODULES
782         return register_module_notifier(&kunit_mod_nb);
783 #else
784         return 0;
785 #endif
786 }
787 late_initcall(kunit_init);
788
789 static void __exit kunit_exit(void)
790 {
791 #ifdef CONFIG_MODULES
792         unregister_module_notifier(&kunit_mod_nb);
793 #endif
794         kunit_debugfs_cleanup();
795 }
796 module_exit(kunit_exit);
797
798 MODULE_LICENSE("GPL v2");
This page took 0.080663 seconds and 4 git commands to generate.