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