brintos

brintos / linux-shallow public Read only

0
0
Text · 23.6 KiB · 089c832 Raw
962 lines · c
1// SPDX-License-Identifier: GPL-2.02/*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 <kunit/attributes.h>13#include <linux/kernel.h>14#include <linux/module.h>15#include <linux/moduleparam.h>16#include <linux/mutex.h>17#include <linux/panic.h>18#include <linux/sched/debug.h>19#include <linux/sched.h>20#include <linux/mm.h>21 22#include "debugfs.h"23#include "device-impl.h"24#include "hooks-impl.h"25#include "string-stream.h"26#include "try-catch-impl.h"27 28static DEFINE_MUTEX(kunit_run_lock);29 30/*31 * Hook to fail the current test and print an error message to the log.32 */33void __printf(3, 4) __kunit_fail_current_test_impl(const char *file, int line, const char *fmt, ...)34{35	va_list args;36	int len;37	char *buffer;38 39	if (!current->kunit_test)40		return;41 42	kunit_set_failure(current->kunit_test);43 44	/* kunit_err() only accepts literals, so evaluate the args first. */45	va_start(args, fmt);46	len = vsnprintf(NULL, 0, fmt, args) + 1;47	va_end(args);48 49	buffer = kunit_kmalloc(current->kunit_test, len, GFP_KERNEL);50	if (!buffer)51		return;52 53	va_start(args, fmt);54	vsnprintf(buffer, len, fmt, args);55	va_end(args);56 57	kunit_err(current->kunit_test, "%s:%d: %s", file, line, buffer);58	kunit_kfree(current->kunit_test, buffer);59}60 61/*62 * Enable KUnit tests to run.63 */64#ifdef CONFIG_KUNIT_DEFAULT_ENABLED65static bool enable_param = true;66#else67static bool enable_param;68#endif69module_param_named(enable, enable_param, bool, 0);70MODULE_PARM_DESC(enable, "Enable KUnit tests");71 72/*73 * KUnit statistic mode:74 * 0 - disabled75 * 1 - only when there is more than one subtest76 * 2 - enabled77 */78static int kunit_stats_enabled = 1;79module_param_named(stats_enabled, kunit_stats_enabled, int, 0644);80MODULE_PARM_DESC(stats_enabled,81		  "Print test stats: never (0), only for multiple subtests (1), or always (2)");82 83struct kunit_result_stats {84	unsigned long passed;85	unsigned long skipped;86	unsigned long failed;87	unsigned long total;88};89 90static bool kunit_should_print_stats(struct kunit_result_stats stats)91{92	if (kunit_stats_enabled == 0)93		return false;94 95	if (kunit_stats_enabled == 2)96		return true;97 98	return (stats.total > 1);99}100 101static void kunit_print_test_stats(struct kunit *test,102				   struct kunit_result_stats stats)103{104	if (!kunit_should_print_stats(stats))105		return;106 107	kunit_log(KERN_INFO, test,108		  KUNIT_SUBTEST_INDENT109		  "# %s: pass:%lu fail:%lu skip:%lu total:%lu",110		  test->name,111		  stats.passed,112		  stats.failed,113		  stats.skipped,114		  stats.total);115}116 117/* Append formatted message to log. */118void kunit_log_append(struct string_stream *log, const char *fmt, ...)119{120	va_list args;121 122	if (!log)123		return;124 125	va_start(args, fmt);126	string_stream_vadd(log, fmt, args);127	va_end(args);128}129EXPORT_SYMBOL_GPL(kunit_log_append);130 131size_t kunit_suite_num_test_cases(struct kunit_suite *suite)132{133	struct kunit_case *test_case;134	size_t len = 0;135 136	kunit_suite_for_each_test_case(suite, test_case)137		len++;138 139	return len;140}141EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);142 143/* Currently supported test levels */144enum {145	KUNIT_LEVEL_SUITE = 0,146	KUNIT_LEVEL_CASE,147	KUNIT_LEVEL_CASE_PARAM,148};149 150static void kunit_print_suite_start(struct kunit_suite *suite)151{152	/*153	 * We do not log the test suite header as doing so would154	 * mean debugfs display would consist of the test suite155	 * header prior to individual test results.156	 * Hence directly printk the suite status, and we will157	 * separately seq_printf() the suite header for the debugfs158	 * representation.159	 */160	pr_info(KUNIT_SUBTEST_INDENT "KTAP version 1\n");161	pr_info(KUNIT_SUBTEST_INDENT "# Subtest: %s\n",162		  suite->name);163	kunit_print_attr((void *)suite, false, KUNIT_LEVEL_CASE);164	pr_info(KUNIT_SUBTEST_INDENT "1..%zd\n",165		  kunit_suite_num_test_cases(suite));166}167 168static void kunit_print_ok_not_ok(struct kunit *test,169				  unsigned int test_level,170				  enum kunit_status status,171				  size_t test_number,172				  const char *description,173				  const char *directive)174{175	const char *directive_header = (status == KUNIT_SKIPPED) ? " # SKIP " : "";176	const char *directive_body = (status == KUNIT_SKIPPED) ? directive : "";177 178	/*179	 * When test is NULL assume that results are from the suite180	 * and today suite results are expected at level 0 only.181	 */182	WARN(!test && test_level, "suite test level can't be %u!\n", test_level);183 184	/*185	 * We do not log the test suite results as doing so would186	 * mean debugfs display would consist of an incorrect test187	 * number. Hence directly printk the suite result, and we will188	 * separately seq_printf() the suite results for the debugfs189	 * representation.190	 */191	if (!test)192		pr_info("%s %zd %s%s%s\n",193			kunit_status_to_ok_not_ok(status),194			test_number, description, directive_header,195			directive_body);196	else197		kunit_log(KERN_INFO, test,198			  "%*s%s %zd %s%s%s",199			  KUNIT_INDENT_LEN * test_level, "",200			  kunit_status_to_ok_not_ok(status),201			  test_number, description, directive_header,202			  directive_body);203}204 205enum kunit_status kunit_suite_has_succeeded(struct kunit_suite *suite)206{207	const struct kunit_case *test_case;208	enum kunit_status status = KUNIT_SKIPPED;209 210	if (suite->suite_init_err)211		return KUNIT_FAILURE;212 213	kunit_suite_for_each_test_case(suite, test_case) {214		if (test_case->status == KUNIT_FAILURE)215			return KUNIT_FAILURE;216		else if (test_case->status == KUNIT_SUCCESS)217			status = KUNIT_SUCCESS;218	}219 220	return status;221}222EXPORT_SYMBOL_GPL(kunit_suite_has_succeeded);223 224static size_t kunit_suite_counter = 1;225 226static void kunit_print_suite_end(struct kunit_suite *suite)227{228	kunit_print_ok_not_ok(NULL, KUNIT_LEVEL_SUITE,229			      kunit_suite_has_succeeded(suite),230			      kunit_suite_counter++,231			      suite->name,232			      suite->status_comment);233}234 235unsigned int kunit_test_case_num(struct kunit_suite *suite,236				 struct kunit_case *test_case)237{238	struct kunit_case *tc;239	unsigned int i = 1;240 241	kunit_suite_for_each_test_case(suite, tc) {242		if (tc == test_case)243			return i;244		i++;245	}246 247	return 0;248}249EXPORT_SYMBOL_GPL(kunit_test_case_num);250 251static void kunit_print_string_stream(struct kunit *test,252				      struct string_stream *stream)253{254	struct string_stream_fragment *fragment;255	char *buf;256 257	if (string_stream_is_empty(stream))258		return;259 260	buf = string_stream_get_string(stream);261	if (!buf) {262		kunit_err(test,263			  "Could not allocate buffer, dumping stream:\n");264		list_for_each_entry(fragment, &stream->fragments, node) {265			kunit_err(test, "%s", fragment->fragment);266		}267		kunit_err(test, "\n");268	} else {269		kunit_err(test, "%s", buf);270		kfree(buf);271	}272}273 274static void kunit_fail(struct kunit *test, const struct kunit_loc *loc,275		       enum kunit_assert_type type, const struct kunit_assert *assert,276		       assert_format_t assert_format, const struct va_format *message)277{278	struct string_stream *stream;279 280	kunit_set_failure(test);281 282	stream = kunit_alloc_string_stream(test, GFP_KERNEL);283	if (IS_ERR(stream)) {284		WARN(true,285		     "Could not allocate stream to print failed assertion in %s:%d\n",286		     loc->file,287		     loc->line);288		return;289	}290 291	kunit_assert_prologue(loc, type, stream);292	assert_format(assert, message, stream);293 294	kunit_print_string_stream(test, stream);295 296	kunit_free_string_stream(test, stream);297}298 299void __noreturn __kunit_abort(struct kunit *test)300{301	kunit_try_catch_throw(&test->try_catch); /* Does not return. */302 303	/*304	 * Throw could not abort from test.305	 *306	 * XXX: we should never reach this line! As kunit_try_catch_throw is307	 * marked __noreturn.308	 */309	WARN_ONCE(true, "Throw could not abort from test!\n");310}311EXPORT_SYMBOL_GPL(__kunit_abort);312 313void __kunit_do_failed_assertion(struct kunit *test,314			       const struct kunit_loc *loc,315			       enum kunit_assert_type type,316			       const struct kunit_assert *assert,317			       assert_format_t assert_format,318			       const char *fmt, ...)319{320	va_list args;321	struct va_format message;322	va_start(args, fmt);323 324	message.fmt = fmt;325	message.va = &args;326 327	kunit_fail(test, loc, type, assert, assert_format, &message);328 329	va_end(args);330}331EXPORT_SYMBOL_GPL(__kunit_do_failed_assertion);332 333void kunit_init_test(struct kunit *test, const char *name, struct string_stream *log)334{335	spin_lock_init(&test->lock);336	INIT_LIST_HEAD(&test->resources);337	test->name = name;338	test->log = log;339	if (test->log)340		string_stream_clear(log);341	test->status = KUNIT_SUCCESS;342	test->status_comment[0] = '\0';343}344EXPORT_SYMBOL_GPL(kunit_init_test);345 346/* Only warn when a test takes more than twice the threshold */347#define KUNIT_SPEED_WARNING_MULTIPLIER	2348 349/* Slow tests are defined as taking more than 1s */350#define KUNIT_SPEED_SLOW_THRESHOLD_S	1351 352#define KUNIT_SPEED_SLOW_WARNING_THRESHOLD_S	\353	(KUNIT_SPEED_WARNING_MULTIPLIER * KUNIT_SPEED_SLOW_THRESHOLD_S)354 355#define s_to_timespec64(s) ns_to_timespec64((s) * NSEC_PER_SEC)356 357static void kunit_run_case_check_speed(struct kunit *test,358				       struct kunit_case *test_case,359				       struct timespec64 duration)360{361	struct timespec64 slow_thr =362		s_to_timespec64(KUNIT_SPEED_SLOW_WARNING_THRESHOLD_S);363	enum kunit_speed speed = test_case->attr.speed;364 365	if (timespec64_compare(&duration, &slow_thr) < 0)366		return;367 368	if (speed == KUNIT_SPEED_VERY_SLOW || speed == KUNIT_SPEED_SLOW)369		return;370 371	kunit_warn(test,372		   "Test should be marked slow (runtime: %lld.%09lds)",373		   duration.tv_sec, duration.tv_nsec);374}375 376/*377 * Initializes and runs test case. Does not clean up or do post validations.378 */379static void kunit_run_case_internal(struct kunit *test,380				    struct kunit_suite *suite,381				    struct kunit_case *test_case)382{383	struct timespec64 start, end;384 385	if (suite->init) {386		int ret;387 388		ret = suite->init(test);389		if (ret) {390			kunit_err(test, "failed to initialize: %d\n", ret);391			kunit_set_failure(test);392			return;393		}394	}395 396	ktime_get_ts64(&start);397 398	test_case->run_case(test);399 400	ktime_get_ts64(&end);401 402	kunit_run_case_check_speed(test, test_case, timespec64_sub(end, start));403}404 405static void kunit_case_internal_cleanup(struct kunit *test)406{407	kunit_cleanup(test);408}409 410/*411 * Performs post validations and cleanup after a test case was run.412 * XXX: Should ONLY BE CALLED AFTER kunit_run_case_internal!413 */414static void kunit_run_case_cleanup(struct kunit *test,415				   struct kunit_suite *suite)416{417	if (suite->exit)418		suite->exit(test);419 420	kunit_case_internal_cleanup(test);421}422 423struct kunit_try_catch_context {424	struct kunit *test;425	struct kunit_suite *suite;426	struct kunit_case *test_case;427};428 429static void kunit_try_run_case(void *data)430{431	struct kunit_try_catch_context *ctx = data;432	struct kunit *test = ctx->test;433	struct kunit_suite *suite = ctx->suite;434	struct kunit_case *test_case = ctx->test_case;435 436	current->kunit_test = test;437 438	/*439	 * kunit_run_case_internal may encounter a fatal error; if it does,440	 * abort will be called, this thread will exit, and finally the parent441	 * thread will resume control and handle any necessary clean up.442	 */443	kunit_run_case_internal(test, suite, test_case);444}445 446static void kunit_try_run_case_cleanup(void *data)447{448	struct kunit_try_catch_context *ctx = data;449	struct kunit *test = ctx->test;450	struct kunit_suite *suite = ctx->suite;451 452	current->kunit_test = test;453 454	kunit_run_case_cleanup(test, suite);455}456 457static void kunit_catch_run_case_cleanup(void *data)458{459	struct kunit_try_catch_context *ctx = data;460	struct kunit *test = ctx->test;461	int try_exit_code = kunit_try_catch_get_result(&test->try_catch);462 463	/* It is always a failure if cleanup aborts. */464	kunit_set_failure(test);465 466	if (try_exit_code) {467		/*468		 * Test case could not finish, we have no idea what state it is469		 * in, so don't do clean up.470		 */471		if (try_exit_code == -ETIMEDOUT) {472			kunit_err(test, "test case cleanup timed out\n");473		/*474		 * Unknown internal error occurred preventing test case from475		 * running, so there is nothing to clean up.476		 */477		} else {478			kunit_err(test, "internal error occurred during test case cleanup: %d\n",479				  try_exit_code);480		}481		return;482	}483 484	kunit_err(test, "test aborted during cleanup. continuing without cleaning up\n");485}486 487 488static void kunit_catch_run_case(void *data)489{490	struct kunit_try_catch_context *ctx = data;491	struct kunit *test = ctx->test;492	int try_exit_code = kunit_try_catch_get_result(&test->try_catch);493 494	if (try_exit_code) {495		kunit_set_failure(test);496		/*497		 * Test case could not finish, we have no idea what state it is498		 * in, so don't do clean up.499		 */500		if (try_exit_code == -ETIMEDOUT) {501			kunit_err(test, "test case timed out\n");502		/*503		 * Unknown internal error occurred preventing test case from504		 * running, so there is nothing to clean up.505		 */506		} else {507			kunit_err(test, "internal error occurred preventing test case from running: %d\n",508				  try_exit_code);509		}510		return;511	}512}513 514/*515 * Performs all logic to run a test case. It also catches most errors that516 * occur in a test case and reports them as failures.517 */518static void kunit_run_case_catch_errors(struct kunit_suite *suite,519					struct kunit_case *test_case,520					struct kunit *test)521{522	struct kunit_try_catch_context context;523	struct kunit_try_catch *try_catch;524 525	try_catch = &test->try_catch;526 527	kunit_try_catch_init(try_catch,528			     test,529			     kunit_try_run_case,530			     kunit_catch_run_case);531	context.test = test;532	context.suite = suite;533	context.test_case = test_case;534	kunit_try_catch_run(try_catch, &context);535 536	/* Now run the cleanup */537	kunit_try_catch_init(try_catch,538			     test,539			     kunit_try_run_case_cleanup,540			     kunit_catch_run_case_cleanup);541	kunit_try_catch_run(try_catch, &context);542 543	/* Propagate the parameter result to the test case. */544	if (test->status == KUNIT_FAILURE)545		test_case->status = KUNIT_FAILURE;546	else if (test_case->status != KUNIT_FAILURE && test->status == KUNIT_SUCCESS)547		test_case->status = KUNIT_SUCCESS;548}549 550static void kunit_print_suite_stats(struct kunit_suite *suite,551				    struct kunit_result_stats suite_stats,552				    struct kunit_result_stats param_stats)553{554	if (kunit_should_print_stats(suite_stats)) {555		kunit_log(KERN_INFO, suite,556			  "# %s: pass:%lu fail:%lu skip:%lu total:%lu",557			  suite->name,558			  suite_stats.passed,559			  suite_stats.failed,560			  suite_stats.skipped,561			  suite_stats.total);562	}563 564	if (kunit_should_print_stats(param_stats)) {565		kunit_log(KERN_INFO, suite,566			  "# Totals: pass:%lu fail:%lu skip:%lu total:%lu",567			  param_stats.passed,568			  param_stats.failed,569			  param_stats.skipped,570			  param_stats.total);571	}572}573 574static void kunit_update_stats(struct kunit_result_stats *stats,575			       enum kunit_status status)576{577	switch (status) {578	case KUNIT_SUCCESS:579		stats->passed++;580		break;581	case KUNIT_SKIPPED:582		stats->skipped++;583		break;584	case KUNIT_FAILURE:585		stats->failed++;586		break;587	}588 589	stats->total++;590}591 592static void kunit_accumulate_stats(struct kunit_result_stats *total,593				   struct kunit_result_stats add)594{595	total->passed += add.passed;596	total->skipped += add.skipped;597	total->failed += add.failed;598	total->total += add.total;599}600 601int kunit_run_tests(struct kunit_suite *suite)602{603	char param_desc[KUNIT_PARAM_DESC_SIZE];604	struct kunit_case *test_case;605	struct kunit_result_stats suite_stats = { 0 };606	struct kunit_result_stats total_stats = { 0 };607 608	/* Taint the kernel so we know we've run tests. */609	add_taint(TAINT_TEST, LOCKDEP_STILL_OK);610 611	if (suite->suite_init) {612		suite->suite_init_err = suite->suite_init(suite);613		if (suite->suite_init_err) {614			kunit_err(suite, KUNIT_SUBTEST_INDENT615				  "# failed to initialize (%d)", suite->suite_init_err);616			goto suite_end;617		}618	}619 620	kunit_print_suite_start(suite);621 622	kunit_suite_for_each_test_case(suite, test_case) {623		struct kunit test = { .param_value = NULL, .param_index = 0 };624		struct kunit_result_stats param_stats = { 0 };625 626		kunit_init_test(&test, test_case->name, test_case->log);627		if (test_case->status == KUNIT_SKIPPED) {628			/* Test marked as skip */629			test.status = KUNIT_SKIPPED;630			kunit_update_stats(&param_stats, test.status);631		} else if (!test_case->generate_params) {632			/* Non-parameterised test. */633			test_case->status = KUNIT_SKIPPED;634			kunit_run_case_catch_errors(suite, test_case, &test);635			kunit_update_stats(&param_stats, test.status);636		} else {637			/* Get initial param. */638			param_desc[0] = '\0';639			test.param_value = test_case->generate_params(NULL, param_desc);640			test_case->status = KUNIT_SKIPPED;641			kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT642				  "KTAP version 1\n");643			kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT644				  "# Subtest: %s", test_case->name);645 646			while (test.param_value) {647				kunit_run_case_catch_errors(suite, test_case, &test);648 649				if (param_desc[0] == '\0') {650					snprintf(param_desc, sizeof(param_desc),651						 "param-%d", test.param_index);652				}653 654				kunit_print_ok_not_ok(&test, KUNIT_LEVEL_CASE_PARAM,655						      test.status,656						      test.param_index + 1,657						      param_desc,658						      test.status_comment);659 660				kunit_update_stats(&param_stats, test.status);661 662				/* Get next param. */663				param_desc[0] = '\0';664				test.param_value = test_case->generate_params(test.param_value, param_desc);665				test.param_index++;666				test.status = KUNIT_SUCCESS;667				test.status_comment[0] = '\0';668				test.priv = NULL;669			}670		}671 672		kunit_print_attr((void *)test_case, true, KUNIT_LEVEL_CASE);673 674		kunit_print_test_stats(&test, param_stats);675 676		kunit_print_ok_not_ok(&test, KUNIT_LEVEL_CASE, test_case->status,677				      kunit_test_case_num(suite, test_case),678				      test_case->name,679				      test.status_comment);680 681		kunit_update_stats(&suite_stats, test_case->status);682		kunit_accumulate_stats(&total_stats, param_stats);683	}684 685	if (suite->suite_exit)686		suite->suite_exit(suite);687 688	kunit_print_suite_stats(suite, suite_stats, total_stats);689suite_end:690	kunit_print_suite_end(suite);691 692	return 0;693}694EXPORT_SYMBOL_GPL(kunit_run_tests);695 696static void kunit_init_suite(struct kunit_suite *suite)697{698	kunit_debugfs_create_suite(suite);699	suite->status_comment[0] = '\0';700	suite->suite_init_err = 0;701 702	if (suite->log)703		string_stream_clear(suite->log);704}705 706bool kunit_enabled(void)707{708	return enable_param;709}710 711int __kunit_test_suites_init(struct kunit_suite * const * const suites, int num_suites)712{713	unsigned int i;714 715	if (num_suites == 0)716		return 0;717 718	if (!kunit_enabled() && num_suites > 0) {719		pr_info("kunit: disabled\n");720		return 0;721	}722 723	kunit_suite_counter = 1;724 725	/* Use mutex lock to guard against running tests concurrently. */726	if (mutex_lock_interruptible(&kunit_run_lock)) {727		pr_err("kunit: test interrupted\n");728		return -EINTR;729	}730	static_branch_inc(&kunit_running);731 732	for (i = 0; i < num_suites; i++) {733		kunit_init_suite(suites[i]);734		kunit_run_tests(suites[i]);735	}736 737	static_branch_dec(&kunit_running);738	mutex_unlock(&kunit_run_lock);739	return 0;740}741EXPORT_SYMBOL_GPL(__kunit_test_suites_init);742 743static void kunit_exit_suite(struct kunit_suite *suite)744{745	kunit_debugfs_destroy_suite(suite);746}747 748void __kunit_test_suites_exit(struct kunit_suite **suites, int num_suites)749{750	unsigned int i;751 752	if (!kunit_enabled())753		return;754 755	for (i = 0; i < num_suites; i++)756		kunit_exit_suite(suites[i]);757}758EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);759 760#ifdef CONFIG_MODULES761static void kunit_module_init(struct module *mod)762{763	struct kunit_suite_set suite_set, filtered_set;764	struct kunit_suite_set normal_suite_set = {765		mod->kunit_suites, mod->kunit_suites + mod->num_kunit_suites,766	};767	struct kunit_suite_set init_suite_set = {768		mod->kunit_init_suites, mod->kunit_init_suites + mod->num_kunit_init_suites,769	};770	const char *action = kunit_action();771	int err = 0;772 773	if (mod->num_kunit_init_suites > 0)774		suite_set = kunit_merge_suite_sets(init_suite_set, normal_suite_set);775	else776		suite_set = normal_suite_set;777 778	filtered_set = kunit_filter_suites(&suite_set,779					kunit_filter_glob() ?: "*.*",780					kunit_filter(), kunit_filter_action(),781					&err);782	if (err)783		pr_err("kunit module: error filtering suites: %d\n", err);784 785	mod->kunit_suites = (struct kunit_suite **)filtered_set.start;786	mod->num_kunit_suites = filtered_set.end - filtered_set.start;787 788	if (mod->num_kunit_init_suites > 0)789		kfree(suite_set.start);790 791	if (!action)792		kunit_exec_run_tests(&filtered_set, false);793	else if (!strcmp(action, "list"))794		kunit_exec_list_tests(&filtered_set, false);795	else if (!strcmp(action, "list_attr"))796		kunit_exec_list_tests(&filtered_set, true);797	else798		pr_err("kunit: unknown action '%s'\n", action);799}800 801static void kunit_module_exit(struct module *mod)802{803	struct kunit_suite_set suite_set = {804		mod->kunit_suites, mod->kunit_suites + mod->num_kunit_suites,805	};806	const char *action = kunit_action();807 808	/*809	 * Check if the start address is a valid virtual address to detect810	 * if the module load sequence has failed and the suite set has not811	 * been initialized and filtered.812	 */813	if (!suite_set.start || !virt_addr_valid(suite_set.start))814		return;815 816	if (!action)817		__kunit_test_suites_exit(mod->kunit_suites,818					 mod->num_kunit_suites);819 820	kunit_free_suite_set(suite_set);821}822 823static int kunit_module_notify(struct notifier_block *nb, unsigned long val,824			       void *data)825{826	struct module *mod = data;827 828	switch (val) {829	case MODULE_STATE_LIVE:830		kunit_module_init(mod);831		break;832	case MODULE_STATE_GOING:833		kunit_module_exit(mod);834		break;835	case MODULE_STATE_COMING:836		break;837	case MODULE_STATE_UNFORMED:838		break;839	}840 841	return 0;842}843 844static struct notifier_block kunit_mod_nb = {845	.notifier_call = kunit_module_notify,846	.priority = 0,847};848#endif849 850KUNIT_DEFINE_ACTION_WRAPPER(kfree_action_wrapper, kfree, const void *)851 852void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp)853{854	void *data;855 856	data = kmalloc_array(n, size, gfp);857 858	if (!data)859		return NULL;860 861	if (kunit_add_action_or_reset(test, kfree_action_wrapper, data) != 0)862		return NULL;863 864	return data;865}866EXPORT_SYMBOL_GPL(kunit_kmalloc_array);867 868void kunit_kfree(struct kunit *test, const void *ptr)869{870	if (!ptr)871		return;872 873	kunit_release_action(test, kfree_action_wrapper, (void *)ptr);874}875EXPORT_SYMBOL_GPL(kunit_kfree);876 877void kunit_kfree_const(struct kunit *test, const void *x)878{879#if !IS_MODULE(CONFIG_KUNIT)880	if (!is_kernel_rodata((unsigned long)x))881#endif882		kunit_kfree(test, x);883}884EXPORT_SYMBOL_GPL(kunit_kfree_const);885 886const char *kunit_kstrdup_const(struct kunit *test, const char *str, gfp_t gfp)887{888#if !IS_MODULE(CONFIG_KUNIT)889	if (is_kernel_rodata((unsigned long)str))890		return str;891#endif892	return kunit_kstrdup(test, str, gfp);893}894EXPORT_SYMBOL_GPL(kunit_kstrdup_const);895 896void kunit_cleanup(struct kunit *test)897{898	struct kunit_resource *res;899	unsigned long flags;900 901	/*902	 * test->resources is a stack - each allocation must be freed in the903	 * reverse order from which it was added since one resource may depend904	 * on another for its entire lifetime.905	 * Also, we cannot use the normal list_for_each constructs, even the906	 * safe ones because *arbitrary* nodes may be deleted when907	 * kunit_resource_free is called; the list_for_each_safe variants only908	 * protect against the current node being deleted, not the next.909	 */910	while (true) {911		spin_lock_irqsave(&test->lock, flags);912		if (list_empty(&test->resources)) {913			spin_unlock_irqrestore(&test->lock, flags);914			break;915		}916		res = list_last_entry(&test->resources,917				      struct kunit_resource,918				      node);919		/*920		 * Need to unlock here as a resource may remove another921		 * resource, and this can't happen if the test->lock922		 * is held.923		 */924		spin_unlock_irqrestore(&test->lock, flags);925		kunit_remove_resource(test, res);926	}927	current->kunit_test = NULL;928}929EXPORT_SYMBOL_GPL(kunit_cleanup);930 931static int __init kunit_init(void)932{933	/* Install the KUnit hook functions. */934	kunit_install_hooks();935 936	kunit_debugfs_init();937 938	kunit_bus_init();939#ifdef CONFIG_MODULES940	return register_module_notifier(&kunit_mod_nb);941#else942	return 0;943#endif944}945late_initcall(kunit_init);946 947static void __exit kunit_exit(void)948{949	memset(&kunit_hooks, 0, sizeof(kunit_hooks));950#ifdef CONFIG_MODULES951	unregister_module_notifier(&kunit_mod_nb);952#endif953 954	kunit_bus_shutdown();955 956	kunit_debugfs_cleanup();957}958module_exit(kunit_exit);959 960MODULE_DESCRIPTION("Base unit test (KUnit) API");961MODULE_LICENSE("GPL v2");962