Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+253 -253
+3 -3
lib/Kconfig.debug
··· 1841 1841 memtest=17, mean do 17 test patterns. 1842 1842 If you are unsure how to answer this question, answer N. 1843 1843 1844 - config TEST_JUMP_LABEL 1845 - tristate "Test jump label" 1844 + config TEST_STATIC_KEYS 1845 + tristate "Test static keys" 1846 1846 default n 1847 1847 depends on m 1848 1848 help 1849 - Test jump labels. 1849 + Test the static key interfaces. 1850 1850 1851 1851 If unsure, say N. 1852 1852
+2 -2
lib/Makefile
··· 39 39 obj-$(CONFIG_TEST_LKM) += test_module.o 40 40 obj-$(CONFIG_TEST_RHASHTABLE) += test_rhashtable.o 41 41 obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o 42 - obj-$(CONFIG_TEST_JUMP_LABEL) += test_jump_label.o 43 - obj-$(CONFIG_TEST_JUMP_LABEL) += test_jump_label_base.o 42 + obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o 43 + obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o 44 44 45 45 ifeq ($(CONFIG_DEBUG_KOBJECT),y) 46 46 CFLAGS_kobject.o += -DDEBUG
-225
lib/test_jump_label.c
··· 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 */ 23 - struct static_key old_true_key = STATIC_KEY_INIT_TRUE; 24 - struct static_key old_false_key = STATIC_KEY_INIT_FALSE; 25 - 26 - /* new api */ 27 - DEFINE_STATIC_KEY_TRUE(true_key); 28 - DEFINE_STATIC_KEY_FALSE(false_key); 29 - 30 - /* external */ 31 - extern struct static_key base_old_true_key; 32 - extern struct static_key base_inv_old_true_key; 33 - extern struct static_key base_old_false_key; 34 - extern struct static_key base_inv_old_false_key; 35 - 36 - /* new api */ 37 - extern struct static_key_true base_true_key; 38 - extern struct static_key_true base_inv_true_key; 39 - extern struct static_key_false base_false_key; 40 - extern struct static_key_false base_inv_false_key; 41 - 42 - 43 - struct 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 - 52 - static 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 - 60 - static 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 - 73 - int 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 - 95 - static 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; 213 - out: 214 - return ret; 215 - } 216 - 217 - static void __exit test_jump_label_exit(void) 218 - { 219 - } 220 - 221 - module_init(test_jump_label_init); 222 - module_exit(test_jump_label_exit); 223 - 224 - MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>"); 225 - MODULE_LICENSE("GPL");
+5 -5
lib/test_jump_label_base.c lib/test_static_key_base.c
··· 1 1 /* 2 - * Kernel module for testing jump labels. 2 + * Kernel module for testing static keys. 3 3 * 4 4 * Copyright 2015 Akamai Technologies Inc. All Rights Reserved 5 5 * ··· 47 47 static_key_enable(key); 48 48 } 49 49 50 - static int __init test_jump_label_base_init(void) 50 + static int __init test_static_key_base_init(void) 51 51 { 52 52 invert_key(&base_inv_old_true_key); 53 53 invert_key(&base_inv_old_false_key); ··· 57 57 return 0; 58 58 } 59 59 60 - static void __exit test_jump_label_base_exit(void) 60 + static void __exit test_static_key_base_exit(void) 61 61 { 62 62 } 63 63 64 - module_init(test_jump_label_base_init); 65 - module_exit(test_jump_label_base_exit); 64 + module_init(test_static_key_base_init); 65 + module_exit(test_static_key_base_exit); 66 66 67 67 MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>"); 68 68 MODULE_LICENSE("GPL");
+225
lib/test_static_keys.c
··· 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 */ 23 + struct static_key old_true_key = STATIC_KEY_INIT_TRUE; 24 + struct static_key old_false_key = STATIC_KEY_INIT_FALSE; 25 + 26 + /* new api */ 27 + DEFINE_STATIC_KEY_TRUE(true_key); 28 + DEFINE_STATIC_KEY_FALSE(false_key); 29 + 30 + /* external */ 31 + extern struct static_key base_old_true_key; 32 + extern struct static_key base_inv_old_true_key; 33 + extern struct static_key base_old_false_key; 34 + extern struct static_key base_inv_old_false_key; 35 + 36 + /* new api */ 37 + extern struct static_key_true base_true_key; 38 + extern struct static_key_true base_inv_true_key; 39 + extern struct static_key_false base_false_key; 40 + extern struct static_key_false base_inv_false_key; 41 + 42 + 43 + struct 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 + 52 + static 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 + 60 + static 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 + 73 + int 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 + 95 + static 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; 213 + out: 214 + return ret; 215 + } 216 + 217 + static void __exit test_static_key_exit(void) 218 + { 219 + } 220 + 221 + module_init(test_static_key_init); 222 + module_exit(test_static_key_exit); 223 + 224 + MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>"); 225 + MODULE_LICENSE("GPL");
+2 -2
tools/testing/selftests/jumplabel/Makefile tools/testing/selftests/static_keys/Makefile
··· 1 - # Makefile for jump label selftests 1 + # Makefile for static keys selftests 2 2 3 3 # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 4 4 all: 5 5 6 - TEST_PROGS := test_jump_label.sh 6 + TEST_PROGS := test_static_keys.sh 7 7 8 8 include ../lib.mk
-16
tools/testing/selftests/jumplabel/test_jump_label.sh
··· 1 - #!/bin/sh 2 - # Runs jump label kernel module tests 3 - 4 - if /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 13 - else 14 - echo "jump_label: [FAIL]" 15 - exit 1 16 - fi
+16
tools/testing/selftests/static_keys/test_static_keys.sh
··· 1 + #!/bin/sh 2 + # Runs static keys kernel module tests 3 + 4 + if /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 13 + else 14 + echo "static_key: [FAIL]" 15 + exit 1 16 + fi