1 // SPDX-License-Identifier: GPL-2.0-only
3 * Kernel module for testing static keys.
5 * Copyright 2015 Akamai Technologies Inc. All Rights Reserved
8 * Jason Baron <jbaron@akamai.com>
11 #include <linux/module.h>
12 #include <linux/jump_label.h>
15 struct static_key old_true_key
= STATIC_KEY_INIT_TRUE
;
16 struct static_key old_false_key
= STATIC_KEY_INIT_FALSE
;
19 DEFINE_STATIC_KEY_TRUE(true_key
);
20 DEFINE_STATIC_KEY_FALSE(false_key
);
23 extern struct static_key base_old_true_key
;
24 extern struct static_key base_inv_old_true_key
;
25 extern struct static_key base_old_false_key
;
26 extern struct static_key base_inv_old_false_key
;
29 extern struct static_key_true base_true_key
;
30 extern struct static_key_true base_inv_true_key
;
31 extern struct static_key_false base_false_key
;
32 extern struct static_key_false base_inv_false_key
;
37 struct static_key
*key
;
38 bool (*test_key
)(void);
41 #define test_key_func(key, branch) \
42 static bool key ## _ ## branch(void) \
44 return branch(&key); \
47 static void invert_key(struct static_key
*key
)
49 if (static_key_enabled(key
))
50 static_key_disable(key
);
52 static_key_enable(key
);
55 static void invert_keys(struct test_key
*keys
, int size
)
57 struct static_key
*previous
= NULL
;
60 for (i
= 0; i
< size
; i
++) {
61 if (previous
!= keys
[i
].key
) {
62 invert_key(keys
[i
].key
);
63 previous
= keys
[i
].key
;
68 static int verify_keys(struct test_key
*keys
, int size
, bool invert
)
73 for (i
= 0; i
< size
; i
++) {
74 ret
= static_key_enabled(keys
[i
].key
);
75 init
= keys
[i
].init_state
;
76 if (ret
!= (invert
? !init
: init
))
78 ret
= keys
[i
].test_key();
79 if (static_key_enabled(keys
[i
].key
)) {
90 test_key_func(old_true_key
, static_key_true
)
91 test_key_func(old_false_key
, static_key_false
)
92 test_key_func(true_key
, static_branch_likely
)
93 test_key_func(true_key
, static_branch_unlikely
)
94 test_key_func(false_key
, static_branch_likely
)
95 test_key_func(false_key
, static_branch_unlikely
)
96 test_key_func(base_old_true_key
, static_key_true
)
97 test_key_func(base_inv_old_true_key
, static_key_true
)
98 test_key_func(base_old_false_key
, static_key_false
)
99 test_key_func(base_inv_old_false_key
, static_key_false
)
100 test_key_func(base_true_key
, static_branch_likely
)
101 test_key_func(base_true_key
, static_branch_unlikely
)
102 test_key_func(base_inv_true_key
, static_branch_likely
)
103 test_key_func(base_inv_true_key
, static_branch_unlikely
)
104 test_key_func(base_false_key
, static_branch_likely
)
105 test_key_func(base_false_key
, static_branch_unlikely
)
106 test_key_func(base_inv_false_key
, static_branch_likely
)
107 test_key_func(base_inv_false_key
, static_branch_unlikely
)
109 static int __init
test_static_key_init(void)
114 struct test_key static_key_tests
[] = {
115 /* internal keys - old keys */
118 .key
= &old_true_key
,
119 .test_key
= &old_true_key_static_key_true
,
123 .key
= &old_false_key
,
124 .test_key
= &old_false_key_static_key_false
,
126 /* internal keys - new keys */
129 .key
= &true_key
.key
,
130 .test_key
= &true_key_static_branch_likely
,
134 .key
= &true_key
.key
,
135 .test_key
= &true_key_static_branch_unlikely
,
139 .key
= &false_key
.key
,
140 .test_key
= &false_key_static_branch_likely
,
144 .key
= &false_key
.key
,
145 .test_key
= &false_key_static_branch_unlikely
,
147 /* external keys - old keys */
150 .key
= &base_old_true_key
,
151 .test_key
= &base_old_true_key_static_key_true
,
155 .key
= &base_inv_old_true_key
,
156 .test_key
= &base_inv_old_true_key_static_key_true
,
160 .key
= &base_old_false_key
,
161 .test_key
= &base_old_false_key_static_key_false
,
165 .key
= &base_inv_old_false_key
,
166 .test_key
= &base_inv_old_false_key_static_key_false
,
168 /* external keys - new keys */
171 .key
= &base_true_key
.key
,
172 .test_key
= &base_true_key_static_branch_likely
,
176 .key
= &base_true_key
.key
,
177 .test_key
= &base_true_key_static_branch_unlikely
,
181 .key
= &base_inv_true_key
.key
,
182 .test_key
= &base_inv_true_key_static_branch_likely
,
186 .key
= &base_inv_true_key
.key
,
187 .test_key
= &base_inv_true_key_static_branch_unlikely
,
191 .key
= &base_false_key
.key
,
192 .test_key
= &base_false_key_static_branch_likely
,
196 .key
= &base_false_key
.key
,
197 .test_key
= &base_false_key_static_branch_unlikely
,
201 .key
= &base_inv_false_key
.key
,
202 .test_key
= &base_inv_false_key_static_branch_likely
,
206 .key
= &base_inv_false_key
.key
,
207 .test_key
= &base_inv_false_key_static_branch_unlikely
,
211 size
= ARRAY_SIZE(static_key_tests
);
213 ret
= verify_keys(static_key_tests
, size
, false);
217 invert_keys(static_key_tests
, size
);
218 ret
= verify_keys(static_key_tests
, size
, true);
222 invert_keys(static_key_tests
, size
);
223 ret
= verify_keys(static_key_tests
, size
, false);
231 static void __exit
test_static_key_exit(void)
235 module_init(test_static_key_init
);
236 module_exit(test_static_key_exit
);
238 MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
239 MODULE_DESCRIPTION("Kernel module for testing static keys");
240 MODULE_LICENSE("GPL");