aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-08-03 05:42:57 -0400
committerIngo Molnar <mingo@kernel.org>2015-08-03 05:51:12 -0400
commit2bf9e0ab08c64ac56067555911a1ae81ebff5f96 (patch)
treea24fff21bdf23d155f6a2514956f94be0578a5ce
parent579e1acb153464649781fe5555b4892c0ff84a40 (diff)
locking/static_keys: Provide a selftest
The 'jump label' self-test is in reality testing static keys - rename things accordingly. Also prettify the code in various places while at it. Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Jason Baron <jbaron@akamai.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Shuah Khan <shuahkh@osg.samsung.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: benh@kernel.crashing.org Cc: bp@alien8.de Cc: davem@davemloft.net Cc: ddaney@caviumnetworks.com Cc: heiko.carstens@de.ibm.com Cc: linux-kernel@vger.kernel.org Cc: liuj97@gmail.com Cc: luto@amacapital.net Cc: michael@ellerman.id.au Cc: rabin@rab.in Cc: ralf@linux-mips.org Cc: rostedt@goodmis.org Cc: vbabka@suse.cz Cc: will.deacon@arm.com Link: http://lkml.kernel.org/r/0c091ecebd78a879ed8a71835d205a691a75ab4e.1438227999.git.jbaron@akamai.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--lib/Kconfig.debug6
-rw-r--r--lib/Makefile4
-rw-r--r--lib/test_jump_label.c225
-rw-r--r--lib/test_static_key_base.c (renamed from lib/test_jump_label_base.c)10
-rw-r--r--lib/test_static_keys.c225
-rw-r--r--tools/testing/selftests/jumplabel/test_jump_label.sh16
-rw-r--r--tools/testing/selftests/static_keys/Makefile (renamed from tools/testing/selftests/jumplabel/Makefile)4
-rw-r--r--tools/testing/selftests/static_keys/test_static_keys.sh16
8 files changed, 253 insertions, 253 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 304e75f832dc..0d859305c556 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1841,12 +1841,12 @@ config MEMTEST
1841 memtest=17, mean do 17 test patterns. 1841 memtest=17, mean do 17 test patterns.
1842 If you are unsure how to answer this question, answer N. 1842 If you are unsure how to answer this question, answer N.
1843 1843
1844config TEST_JUMP_LABEL 1844config TEST_STATIC_KEYS
1845 tristate "Test jump label" 1845 tristate "Test static keys"
1846 default n 1846 default n
1847 depends on m 1847 depends on m
1848 help 1848 help
1849 Test jump labels. 1849 Test the static key interfaces.
1850 1850
1851 If unsure, say N. 1851 If unsure, say N.
1852 1852
diff --git a/lib/Makefile b/lib/Makefile
index 14f6e07e33a8..9f2fc71a14a3 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -39,8 +39,8 @@ obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o
39obj-$(CONFIG_TEST_LKM) += test_module.o 39obj-$(CONFIG_TEST_LKM) += test_module.o
40obj-$(CONFIG_TEST_RHASHTABLE) += test_rhashtable.o 40obj-$(CONFIG_TEST_RHASHTABLE) += test_rhashtable.o
41obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o 41obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o
42obj-$(CONFIG_TEST_JUMP_LABEL) += test_jump_label.o 42obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o
43obj-$(CONFIG_TEST_JUMP_LABEL) += test_jump_label_base.o 43obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
44 44
45ifeq ($(CONFIG_DEBUG_KOBJECT),y) 45ifeq ($(CONFIG_DEBUG_KOBJECT),y)
46CFLAGS_kobject.o += -DDEBUG 46CFLAGS_kobject.o += -DDEBUG
diff --git a/lib/test_jump_label.c b/lib/test_jump_label.c
deleted file mode 100644
index 2fe741329b0e..000000000000
--- a/lib/test_jump_label.c
+++ /dev/null
@@ -1,225 +0,0 @@
1/*
2 * Kernel module for testing jump labels.
3 *
4 * Copyright 2015 Akamai Technologies Inc. All Rights Reserved
5 *
6 * Authors:
7 * Jason Baron <jbaron@akamai.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/module.h>
20#include <linux/jump_label.h>
21
22/* old keys */
23struct static_key old_true_key = STATIC_KEY_INIT_TRUE;
24struct static_key old_false_key = STATIC_KEY_INIT_FALSE;
25
26/* new api */
27DEFINE_STATIC_KEY_TRUE(true_key);
28DEFINE_STATIC_KEY_FALSE(false_key);
29
30/* external */
31extern struct static_key base_old_true_key;
32extern struct static_key base_inv_old_true_key;
33extern struct static_key base_old_false_key;
34extern struct static_key base_inv_old_false_key;
35
36/* new api */
37extern struct static_key_true base_true_key;
38extern struct static_key_true base_inv_true_key;
39extern struct static_key_false base_false_key;
40extern struct static_key_false base_inv_false_key;
41
42
43struct test_branch {
44 bool init_state;
45 struct static_key *key;
46 bool (*test_key)(void);
47};
48
49#define test_key_func(key, branch) \
50({bool func(void) { return branch(key); } func; })
51
52static void invert_key(struct static_key *key)
53{
54 if (static_key_enabled(key))
55 static_key_disable(key);
56 else
57 static_key_enable(key);
58}
59
60static void invert_keys(struct test_branch *branches, int size)
61{
62 struct static_key *previous = NULL;
63 int i;
64
65 for (i = 0; i < size; i++) {
66 if (previous != branches[i].key) {
67 invert_key(branches[i].key);
68 previous = branches[i].key;
69 }
70 }
71}
72
73int verify_branches(struct test_branch *branches, int size, bool invert)
74{
75 int i;
76 bool ret, init;
77
78 for (i = 0; i < size; i++) {
79 ret = static_key_enabled(branches[i].key);
80 init = branches[i].init_state;
81 if (ret != (invert ? !init : init))
82 return -EINVAL;
83 ret = branches[i].test_key();
84 if (static_key_enabled(branches[i].key)) {
85 if (!ret)
86 return -EINVAL;
87 } else {
88 if (ret)
89 return -EINVAL;
90 }
91 }
92 return 0;
93}
94
95static int __init test_jump_label_init(void)
96{
97 int ret;
98 int size;
99
100 struct test_branch jump_label_tests[] = {
101 /* internal keys - old keys */
102 {
103 .init_state = true,
104 .key = &old_true_key,
105 .test_key = test_key_func(&old_true_key, static_key_true),
106 },
107 {
108 .init_state = false,
109 .key = &old_false_key,
110 .test_key = test_key_func(&old_false_key, static_key_false),
111 },
112 /* internal keys - new keys */
113 {
114 .init_state = true,
115 .key = &true_key.key,
116 .test_key = test_key_func(&true_key, static_branch_likely),
117 },
118 {
119 .init_state = true,
120 .key = &true_key.key,
121 .test_key = test_key_func(&true_key, static_branch_unlikely),
122 },
123 {
124 .init_state = false,
125 .key = &false_key.key,
126 .test_key = test_key_func(&false_key, static_branch_likely),
127 },
128 {
129 .init_state = false,
130 .key = &false_key.key,
131 .test_key = test_key_func(&false_key, static_branch_unlikely),
132 },
133 /* external keys - old keys */
134 {
135 .init_state = true,
136 .key = &base_old_true_key,
137 .test_key = test_key_func(&base_old_true_key, static_key_true),
138 },
139 {
140 .init_state = false,
141 .key = &base_inv_old_true_key,
142 .test_key = test_key_func(&base_inv_old_true_key, static_key_true),
143 },
144 {
145 .init_state = false,
146 .key = &base_old_false_key,
147 .test_key = test_key_func(&base_old_false_key, static_key_false),
148 },
149 {
150 .init_state = true,
151 .key = &base_inv_old_false_key,
152 .test_key = test_key_func(&base_inv_old_false_key, static_key_false),
153 },
154 /* external keys - new keys */
155 {
156 .init_state = true,
157 .key = &base_true_key.key,
158 .test_key = test_key_func(&base_true_key, static_branch_likely),
159 },
160 {
161 .init_state = true,
162 .key = &base_true_key.key,
163 .test_key = test_key_func(&base_true_key, static_branch_unlikely),
164 },
165 {
166 .init_state = false,
167 .key = &base_inv_true_key.key,
168 .test_key = test_key_func(&base_inv_true_key, static_branch_likely),
169 },
170 {
171 .init_state = false,
172 .key = &base_inv_true_key.key,
173 .test_key = test_key_func(&base_inv_true_key, static_branch_unlikely),
174 },
175 {
176 .init_state = false,
177 .key = &base_false_key.key,
178 .test_key = test_key_func(&base_false_key, static_branch_likely),
179 },
180 {
181 .init_state = false,
182 .key = &base_false_key.key,
183 .test_key = test_key_func(&base_false_key, static_branch_unlikely),
184 },
185 {
186 .init_state = true,
187 .key = &base_inv_false_key.key,
188 .test_key = test_key_func(&base_inv_false_key, static_branch_likely),
189 },
190 {
191 .init_state = true,
192 .key = &base_inv_false_key.key,
193 .test_key = test_key_func(&base_inv_false_key, static_branch_unlikely),
194 },
195 };
196
197 size = ARRAY_SIZE(jump_label_tests);
198
199 ret = verify_branches(jump_label_tests, size, false);
200 if (ret)
201 goto out;
202
203 invert_keys(jump_label_tests, size);
204 ret = verify_branches(jump_label_tests, size, true);
205 if (ret)
206 goto out;
207
208 invert_keys(jump_label_tests, size);
209 ret = verify_branches(jump_label_tests, size, false);
210 if (ret)
211 goto out;
212 return 0;
213out:
214 return ret;
215}
216
217static void __exit test_jump_label_exit(void)
218{
219}
220
221module_init(test_jump_label_init);
222module_exit(test_jump_label_exit);
223
224MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
225MODULE_LICENSE("GPL");
diff --git a/lib/test_jump_label_base.c b/lib/test_static_key_base.c
index 91aed8e8a7e8..729447aea02f 100644
--- a/lib/test_jump_label_base.c
+++ b/lib/test_static_key_base.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Kernel module for testing jump labels. 2 * Kernel module for testing static keys.
3 * 3 *
4 * Copyright 2015 Akamai Technologies Inc. All Rights Reserved 4 * Copyright 2015 Akamai Technologies Inc. All Rights Reserved
5 * 5 *
@@ -47,7 +47,7 @@ static void invert_key(struct static_key *key)
47 static_key_enable(key); 47 static_key_enable(key);
48} 48}
49 49
50static int __init test_jump_label_base_init(void) 50static int __init test_static_key_base_init(void)
51{ 51{
52 invert_key(&base_inv_old_true_key); 52 invert_key(&base_inv_old_true_key);
53 invert_key(&base_inv_old_false_key); 53 invert_key(&base_inv_old_false_key);
@@ -57,12 +57,12 @@ static int __init test_jump_label_base_init(void)
57 return 0; 57 return 0;
58} 58}
59 59
60static void __exit test_jump_label_base_exit(void) 60static void __exit test_static_key_base_exit(void)
61{ 61{
62} 62}
63 63
64module_init(test_jump_label_base_init); 64module_init(test_static_key_base_init);
65module_exit(test_jump_label_base_exit); 65module_exit(test_static_key_base_exit);
66 66
67MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>"); 67MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
68MODULE_LICENSE("GPL"); 68MODULE_LICENSE("GPL");
diff --git a/lib/test_static_keys.c b/lib/test_static_keys.c
new file mode 100644
index 000000000000..81d81052eb8d
--- /dev/null
+++ b/lib/test_static_keys.c
@@ -0,0 +1,225 @@
1/*
2 * Kernel module for testing static keys.
3 *
4 * Copyright 2015 Akamai Technologies Inc. All Rights Reserved
5 *
6 * Authors:
7 * Jason Baron <jbaron@akamai.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/module.h>
20#include <linux/jump_label.h>
21
22/* old keys */
23struct static_key old_true_key = STATIC_KEY_INIT_TRUE;
24struct static_key old_false_key = STATIC_KEY_INIT_FALSE;
25
26/* new api */
27DEFINE_STATIC_KEY_TRUE(true_key);
28DEFINE_STATIC_KEY_FALSE(false_key);
29
30/* external */
31extern struct static_key base_old_true_key;
32extern struct static_key base_inv_old_true_key;
33extern struct static_key base_old_false_key;
34extern struct static_key base_inv_old_false_key;
35
36/* new api */
37extern struct static_key_true base_true_key;
38extern struct static_key_true base_inv_true_key;
39extern struct static_key_false base_false_key;
40extern struct static_key_false base_inv_false_key;
41
42
43struct test_key {
44 bool init_state;
45 struct static_key *key;
46 bool (*test_key)(void);
47};
48
49#define test_key_func(key, branch) \
50 ({bool func(void) { return branch(key); } func; })
51
52static void invert_key(struct static_key *key)
53{
54 if (static_key_enabled(key))
55 static_key_disable(key);
56 else
57 static_key_enable(key);
58}
59
60static void invert_keys(struct test_key *keys, int size)
61{
62 struct static_key *previous = NULL;
63 int i;
64
65 for (i = 0; i < size; i++) {
66 if (previous != keys[i].key) {
67 invert_key(keys[i].key);
68 previous = keys[i].key;
69 }
70 }
71}
72
73int verify_keys(struct test_key *keys, int size, bool invert)
74{
75 int i;
76 bool ret, init;
77
78 for (i = 0; i < size; i++) {
79 ret = static_key_enabled(keys[i].key);
80 init = keys[i].init_state;
81 if (ret != (invert ? !init : init))
82 return -EINVAL;
83 ret = keys[i].test_key();
84 if (static_key_enabled(keys[i].key)) {
85 if (!ret)
86 return -EINVAL;
87 } else {
88 if (ret)
89 return -EINVAL;
90 }
91 }
92 return 0;
93}
94
95static int __init test_static_key_init(void)
96{
97 int ret;
98 int size;
99
100 struct test_key static_key_tests[] = {
101 /* internal keys - old keys */
102 {
103 .init_state = true,
104 .key = &old_true_key,
105 .test_key = test_key_func(&old_true_key, static_key_true),
106 },
107 {
108 .init_state = false,
109 .key = &old_false_key,
110 .test_key = test_key_func(&old_false_key, static_key_false),
111 },
112 /* internal keys - new keys */
113 {
114 .init_state = true,
115 .key = &true_key.key,
116 .test_key = test_key_func(&true_key, static_branch_likely),
117 },
118 {
119 .init_state = true,
120 .key = &true_key.key,
121 .test_key = test_key_func(&true_key, static_branch_unlikely),
122 },
123 {
124 .init_state = false,
125 .key = &false_key.key,
126 .test_key = test_key_func(&false_key, static_branch_likely),
127 },
128 {
129 .init_state = false,
130 .key = &false_key.key,
131 .test_key = test_key_func(&false_key, static_branch_unlikely),
132 },
133 /* external keys - old keys */
134 {
135 .init_state = true,
136 .key = &base_old_true_key,
137 .test_key = test_key_func(&base_old_true_key, static_key_true),
138 },
139 {
140 .init_state = false,
141 .key = &base_inv_old_true_key,
142 .test_key = test_key_func(&base_inv_old_true_key, static_key_true),
143 },
144 {
145 .init_state = false,
146 .key = &base_old_false_key,
147 .test_key = test_key_func(&base_old_false_key, static_key_false),
148 },
149 {
150 .init_state = true,
151 .key = &base_inv_old_false_key,
152 .test_key = test_key_func(&base_inv_old_false_key, static_key_false),
153 },
154 /* external keys - new keys */
155 {
156 .init_state = true,
157 .key = &base_true_key.key,
158 .test_key = test_key_func(&base_true_key, static_branch_likely),
159 },
160 {
161 .init_state = true,
162 .key = &base_true_key.key,
163 .test_key = test_key_func(&base_true_key, static_branch_unlikely),
164 },
165 {
166 .init_state = false,
167 .key = &base_inv_true_key.key,
168 .test_key = test_key_func(&base_inv_true_key, static_branch_likely),
169 },
170 {
171 .init_state = false,
172 .key = &base_inv_true_key.key,
173 .test_key = test_key_func(&base_inv_true_key, static_branch_unlikely),
174 },
175 {
176 .init_state = false,
177 .key = &base_false_key.key,
178 .test_key = test_key_func(&base_false_key, static_branch_likely),
179 },
180 {
181 .init_state = false,
182 .key = &base_false_key.key,
183 .test_key = test_key_func(&base_false_key, static_branch_unlikely),
184 },
185 {
186 .init_state = true,
187 .key = &base_inv_false_key.key,
188 .test_key = test_key_func(&base_inv_false_key, static_branch_likely),
189 },
190 {
191 .init_state = true,
192 .key = &base_inv_false_key.key,
193 .test_key = test_key_func(&base_inv_false_key, static_branch_unlikely),
194 },
195 };
196
197 size = ARRAY_SIZE(static_key_tests);
198
199 ret = verify_keys(static_key_tests, size, false);
200 if (ret)
201 goto out;
202
203 invert_keys(static_key_tests, size);
204 ret = verify_keys(static_key_tests, size, true);
205 if (ret)
206 goto out;
207
208 invert_keys(static_key_tests, size);
209 ret = verify_keys(static_key_tests, size, false);
210 if (ret)
211 goto out;
212 return 0;
213out:
214 return ret;
215}
216
217static void __exit test_static_key_exit(void)
218{
219}
220
221module_init(test_static_key_init);
222module_exit(test_static_key_exit);
223
224MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
225MODULE_LICENSE("GPL");
diff --git a/tools/testing/selftests/jumplabel/test_jump_label.sh b/tools/testing/selftests/jumplabel/test_jump_label.sh
deleted file mode 100644
index 3457e8a64e77..000000000000
--- a/tools/testing/selftests/jumplabel/test_jump_label.sh
+++ /dev/null
@@ -1,16 +0,0 @@
1#!/bin/sh
2# Runs jump label kernel module tests
3
4if /sbin/modprobe -q test_jump_label_base; then
5 if /sbin/modprobe -q test_jump_label; then
6 echo "jump_label: ok"
7 /sbin/modprobe -q -r test_jump_label
8 /sbin/modprobe -q -r test_jump_label_base
9 else
10 echo "jump_label: [FAIL]"
11 /sbin/modprobe -q -r test_jump_label_base
12 fi
13else
14 echo "jump_label: [FAIL]"
15 exit 1
16fi
diff --git a/tools/testing/selftests/jumplabel/Makefile b/tools/testing/selftests/static_keys/Makefile
index 7526aa59e005..9cdadf37f114 100644
--- a/tools/testing/selftests/jumplabel/Makefile
+++ b/tools/testing/selftests/static_keys/Makefile
@@ -1,8 +1,8 @@
1# Makefile for jump label selftests 1# Makefile for static keys selftests
2 2
3# No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 3# No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
4all: 4all:
5 5
6TEST_PROGS := test_jump_label.sh 6TEST_PROGS := test_static_keys.sh
7 7
8include ../lib.mk 8include ../lib.mk
diff --git a/tools/testing/selftests/static_keys/test_static_keys.sh b/tools/testing/selftests/static_keys/test_static_keys.sh
new file mode 100644
index 000000000000..1261e3fa1e3a
--- /dev/null
+++ b/tools/testing/selftests/static_keys/test_static_keys.sh
@@ -0,0 +1,16 @@
1#!/bin/sh
2# Runs static keys kernel module tests
3
4if /sbin/modprobe -q test_static_key_base; then
5 if /sbin/modprobe -q test_static_keys; then
6 echo "static_key: ok"
7 /sbin/modprobe -q -r test_static_keys
8 /sbin/modprobe -q -r test_static_key_base
9 else
10 echo "static_keys: [FAIL]"
11 /sbin/modprobe -q -r test_static_key_base
12 fi
13else
14 echo "static_key: [FAIL]"
15 exit 1
16fi