History

Merge branch 'for-mingo-kcsan' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into locking/core

Pull KCSAN changes from Paul E. McKenney: misc updates.

Ingo Molnar committed 5 years ago

Commit eedd6342 parents 9432bbd bd0ccc413 files · +111 −76Browse files

Unified · Split

13 files
  1. Documentation/dev-tools/kcsan.rst +3 −0
  2. include/linux/kcsan-checks.h +6 −0
  3. include/linux/kcsan.h +7 −0
  4. kernel/kcsan/Makefile +2 −2
  5. kernel/kcsan/atomic.h +5 −0
  6. kernel/kcsan/core.c +5 −2
  7. kernel/kcsan/debugfs.c +8 −1
  8. kernel/kcsan/encoding.h +5 −0
  9. kernel/kcsan/kcsan.h +2 −6
  10. kernel/kcsan/kcsan_test.c +55 −63
  11. kernel/kcsan/report.c +5 −0
  12. kernel/kcsan/selftest.c +5 −0
  13. lib/Kconfig.kcsan +3 −2
Documentation/dev-tools/kcsan.rst+3−0
@@ -1,3 +1,6 @@
1+.. SPDX-License-Identifier: GPL-2.0
2+.. Copyright (C) 2019, Google LLC.
3+
14 The Kernel Concurrency Sanitizer (KCSAN)
25 ========================================
36
include/linux/kcsan-checks.h+6−0
@@ -1,4 +1,10 @@
11 /* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * KCSAN access checks and modifiers. These can be used to explicitly check
4+ * uninstrumented accesses, or change KCSAN checking behaviour of accesses.
5+ *
6+ * Copyright (C) 2019, Google LLC.
7+ */
28
39 #ifndef _LINUX_KCSAN_CHECKS_H
410 #define _LINUX_KCSAN_CHECKS_H
include/linux/kcsan.h+7−0
@@ -1,4 +1,11 @@
11 /* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * The Kernel Concurrency Sanitizer (KCSAN) infrastructure. Public interface and
4+ * data structures to set up runtime. See kcsan-checks.h for explicit checks and
5+ * modifiers. For more info please see Documentation/dev-tools/kcsan.rst.
6+ *
7+ * Copyright (C) 2019, Google LLC.
8+ */
29
310 #ifndef _LINUX_KCSAN_H
411 #define _LINUX_KCSAN_H
kernel/kcsan/Makefile+2−2
@@ -13,5 +13,5 @@ CFLAGS_core.o := $(call cc-option,-fno-conserve-stack) \ · 12 unmodified lines
1313 obj-y := core.o debugfs.o report.o
1414 obj-$(CONFIG_KCSAN_SELFTEST) += selftest.o
1515
16−CFLAGS_kcsan-test.o := $(CFLAGS_KCSAN) -g -fno-omit-frame-pointer
17−obj-$(CONFIG_KCSAN_TEST) += kcsan-test.o
16+CFLAGS_kcsan_test.o := $(CFLAGS_KCSAN) -g -fno-omit-frame-pointer
17+obj-$(CONFIG_KCSAN_KUNIT_TEST) += kcsan_test.o
kernel/kcsan/atomic.h+5−0
@@ -1,4 +1,9 @@
11 /* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * Rules for implicitly atomic memory accesses.
4+ *
5+ * Copyright (C) 2019, Google LLC.
6+ */
27
38 #ifndef _KERNEL_KCSAN_ATOMIC_H
49 #define _KERNEL_KCSAN_ATOMIC_H
kernel/kcsan/core.c+5−2
@@ -1,4 +1,9 @@
11 // SPDX-License-Identifier: GPL-2.0
2+/*
3+ * KCSAN core runtime.
4+ *
5+ * Copyright (C) 2019, Google LLC.
6+ */
27
38 #define pr_fmt(fmt) "kcsan: " fmt
49
@@ -639,8 +644,6 @@ void __init kcsan_init(void) · 634 unmodified lines
639644
640645 BUG_ON(!in_task());
641646
642− kcsan_debugfs_init();
643−
644647 for_each_possible_cpu(cpu)
645648 per_cpu(kcsan_rand_state, cpu) = (u32)get_cycles();
646649
kernel/kcsan/debugfs.c+8−1
@@ -1,4 +1,9 @@
11 // SPDX-License-Identifier: GPL-2.0
2+/*
3+ * KCSAN debugfs interface.
4+ *
5+ * Copyright (C) 2019, Google LLC.
6+ */
27
38 #define pr_fmt(fmt) "kcsan: " fmt
49
@@ -261,7 +266,9 @@ static const struct file_operations debugfs_ops = · 256 unmodified lines
261266 .release = single_release
262267 };
263268
264−void __init kcsan_debugfs_init(void)
269+static void __init kcsan_debugfs_init(void)
265270 {
266271 debugfs_create_file("kcsan", 0644, NULL, NULL, &debugfs_ops);
267272 }
273+
274+late_initcall(kcsan_debugfs_init);
kernel/kcsan/encoding.h+5−0
@@ -1,4 +1,9 @@
11 /* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * KCSAN watchpoint encoding.
4+ *
5+ * Copyright (C) 2019, Google LLC.
6+ */
27
38 #ifndef _KERNEL_KCSAN_ENCODING_H
49 #define _KERNEL_KCSAN_ENCODING_H
kernel/kcsan/kcsan.h+2−6
@@ -1,8 +1,9 @@
11 /* SPDX-License-Identifier: GPL-2.0 */
2−
32 /*
43 * The Kernel Concurrency Sanitizer (KCSAN) infrastructure. For more info please
54 * see Documentation/dev-tools/kcsan.rst.
5+ *
6+ * Copyright (C) 2019, Google LLC.
67 */
78
89 #ifndef _KERNEL_KCSAN_KCSAN_H
@@ -30,11 +31,6 @@ extern bool kcsan_enabled; · 21 unmodified lines
3031 void kcsan_save_irqtrace(struct task_struct *task);
3132 void kcsan_restore_irqtrace(struct task_struct *task);
3233
33−/*
34− * Initialize debugfs file.
35− */
36−void kcsan_debugfs_init(void);
37−
3834 /*
3935 * Statistics counters displayed via debugfs; should only be modified in
4036 * slow-paths.
kernel/kcsan/kcsan_test.crenamed from kernel/kcsan/kcsan-test.c+55−63
@@ -13,6 +13,8 @@ · 12 unmodified lines
1313 * Author: Marco Elver <elver@google.com>
1414 */
1515
16+#define pr_fmt(fmt) "kcsan_test: " fmt
17+
1618 #include <kunit/test.h>
1719 #include <linux/jiffies.h>
1820 #include <linux/kcsan-checks.h>
@@ -951,22 +953,53 @@ static void test_atomic_builtins(struct kunit *test) · 932 unmodified lines
951953 }
952954
953955 /*
954− * Each test case is run with different numbers of threads. Until KUnit supports
955− * passing arguments for each test case, we encode #threads in the test case
956− * name (read by get_num_threads()). [The '-' was chosen as a stylistic
957− * preference to separate test name and #threads.]
956+ * Generate thread counts for all test cases. Values generated are in interval
957+ * [2, 5] followed by exponentially increasing thread counts from 8 to 32.
958958 *
959959 * The thread counts are chosen to cover potentially interesting boundaries and
960− * corner cases (range 2-5), and then stress the system with larger counts.
960+ * corner cases (2 to 5), and then stress the system with larger counts.
961961 */
962−#define KCSAN_KUNIT_CASE(test_name) \
963− { .run_case = test_name, .name = #test_name "-02" }, \
964− { .run_case = test_name, .name = #test_name "-03" }, \
965− { .run_case = test_name, .name = #test_name "-04" }, \
966− { .run_case = test_name, .name = #test_name "-05" }, \
967− { .run_case = test_name, .name = #test_name "-08" }, \
968− { .run_case = test_name, .name = #test_name "-16" }
962+static const void *nthreads_gen_params(const void *prev, char *desc)
963+{
964+ long nthreads = (long)prev;
965+
966+ if (nthreads < 0 || nthreads >= 32)
967+ nthreads = 0; /* stop */
968+ else if (!nthreads)
969+ nthreads = 2; /* initial value */
970+ else if (nthreads < 5)
971+ nthreads++;
972+ else if (nthreads == 5)
973+ nthreads = 8;
974+ else
975+ nthreads *= 2;
969976
977+ if (!IS_ENABLED(CONFIG_PREEMPT) || !IS_ENABLED(CONFIG_KCSAN_INTERRUPT_WATCHER)) {
978+ /*
979+ * Without any preemption, keep 2 CPUs free for other tasks, one
980+ * of which is the main test case function checking for
981+ * completion or failure.
982+ */
983+ const long min_unused_cpus = IS_ENABLED(CONFIG_PREEMPT_NONE) ? 2 : 0;
984+ const long min_required_cpus = 2 + min_unused_cpus;
985+
986+ if (num_online_cpus() < min_required_cpus) {
987+ pr_err_once("Too few online CPUs (%u < %d) for test\n",
988+ num_online_cpus(), min_required_cpus);
989+ nthreads = 0;
990+ } else if (nthreads >= num_online_cpus() - min_unused_cpus) {
991+ /* Use negative value to indicate last param. */
992+ nthreads = -(num_online_cpus() - min_unused_cpus);
993+ pr_warn_once("Limiting number of threads to %ld (only %d online CPUs)\n",
994+ -nthreads, num_online_cpus());
995+ }
996+ }
997+
998+ snprintf(desc, KUNIT_PARAM_DESC_SIZE, "threads=%ld", abs(nthreads));
999+ return (void *)nthreads;
1000+}
1001+
1002+#define KCSAN_KUNIT_CASE(test_name) KUNIT_CASE_PARAM(test_name, nthreads_gen_params)
9701003 static struct kunit_case kcsan_test_cases[] = {
9711004 KCSAN_KUNIT_CASE(test_basic),
9721005 KCSAN_KUNIT_CASE(test_concurrent_races),
@@ -996,24 +1029,6 @@ static struct kunit_case kcsan_test_cases[] = { · 23 unmodified lines
9961029
9971030 /* ===== End test cases ===== */
9981031
999−/* Get number of threads encoded in test name. */
1000−static bool __no_kcsan
1001−get_num_threads(const char *test, int *nthreads)
1002−{
1003− int len = strlen(test);
1004−
1005− if (WARN_ON(len < 3))
1006− return false;
1007−
1008− *nthreads = test[len - 1] - '0';
1009− *nthreads += (test[len - 2] - '0') * 10;
1010−
1011− if (WARN_ON(*nthreads < 0))
1012− return false;
1013−
1014− return true;
1015−}
1016−
10171032 /* Concurrent accesses from interrupts. */
10181033 __no_kcsan
10191034 static void access_thread_timer(struct timer_list *timer)
@@ -1076,9 +1091,6 @@ static int test_init(struct kunit *test) · 56 unmodified lines
10761091 if (!torture_init_begin((char *)test->name, 1))
10771092 return -EBUSY;
10781093
1079− if (!get_num_threads(test->name, &nthreads))
1080− goto err;
1081−
10821094 if (WARN_ON(threads))
10831095 goto err;
10841096
@@ -1087,38 +1099,18 @@ static int test_init(struct kunit *test) · 2 unmodified lines
10871099 goto err;
10881100 }
10891101
1090− if (!IS_ENABLED(CONFIG_PREEMPT) || !IS_ENABLED(CONFIG_KCSAN_INTERRUPT_WATCHER)) {
1091− /*
1092− * Without any preemption, keep 2 CPUs free for other tasks, one
1093− * of which is the main test case function checking for
1094− * completion or failure.
1095− */
1096− const int min_unused_cpus = IS_ENABLED(CONFIG_PREEMPT_NONE) ? 2 : 0;
1097− const int min_required_cpus = 2 + min_unused_cpus;
1102+ nthreads = abs((long)test->param_value);
1103+ if (WARN_ON(!nthreads))
1104+ goto err;
10981105
1099− if (num_online_cpus() < min_required_cpus) {
1100− pr_err("%s: too few online CPUs (%u < %d) for test",
1101− test->name, num_online_cpus(), min_required_cpus);
1102− goto err;
1103− } else if (nthreads > num_online_cpus() - min_unused_cpus) {
1104− nthreads = num_online_cpus() - min_unused_cpus;
1105− pr_warn("%s: limiting number of threads to %d\n",
1106− test->name, nthreads);
1107− }
1108− }
1106+ threads = kcalloc(nthreads + 1, sizeof(struct task_struct *), GFP_KERNEL);
1107+ if (WARN_ON(!threads))
1108+ goto err;
11091109
1110− if (nthreads) {
1111− threads = kcalloc(nthreads + 1, sizeof(struct task_struct *),
1112− GFP_KERNEL);
1113− if (WARN_ON(!threads))
1110+ threads[nthreads] = NULL;
1111+ for (i = 0; i < nthreads; ++i) {
1112+ if (torture_create_kthread(access_thread, NULL, threads[i]))
11141113 goto err;
1115−
1116− threads[nthreads] = NULL;
1117− for (i = 0; i < nthreads; ++i) {
1118− if (torture_create_kthread(access_thread, NULL,
1119− threads[i]))
1120− goto err;
1121− }
11221114 }
11231115
11241116 torture_init_end();
@@ -1156,7 +1148,7 @@ static void test_exit(struct kunit *test) · 31 unmodified lines
11561148 }
11571149
11581150 static struct kunit_suite kcsan_test_suite = {
1159− .name = "kcsan-test",
1151+ .name = "kcsan",
11601152 .test_cases = kcsan_test_cases,
11611153 .init = test_init,
11621154 .exit = test_exit,
kernel/kcsan/report.c+5−0
@@ -1,4 +1,9 @@
11 // SPDX-License-Identifier: GPL-2.0
2+/*
3+ * KCSAN reporting.
4+ *
5+ * Copyright (C) 2019, Google LLC.
6+ */
27
38 #include <linux/debug_locks.h>
49 #include <linux/delay.h>
kernel/kcsan/selftest.c+5−0
@@ -1,4 +1,9 @@
11 // SPDX-License-Identifier: GPL-2.0
2+/*
3+ * KCSAN short boot-time selftests.
4+ *
5+ * Copyright (C) 2019, Google LLC.
6+ */
27
38 #define pr_fmt(fmt) "kcsan: " fmt
49
lib/Kconfig.kcsan+3−2
@@ -69,8 +69,9 @@ config KCSAN_SELFTEST · 68 unmodified lines
6969 panic. Recommended to be enabled, ensuring critical functionality
7070 works as intended.
7171
72−config KCSAN_TEST
73− tristate "KCSAN test for integrated runtime behaviour"
72+config KCSAN_KUNIT_TEST
73+ tristate "KCSAN test for integrated runtime behaviour" if !KUNIT_ALL_TESTS
74+ default KUNIT_ALL_TESTS
7475 depends on TRACEPOINTS && KUNIT
7576 select TORTURE_TEST
7677 help

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t