Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/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 static bool key ## _ ## branch(void)    \
 51 {                                       \
 52         return branch(&key);            \
 53 }
 54 
 55 static void invert_key(struct static_key *key)
 56 {
 57         if (static_key_enabled(key))
 58                 static_key_disable(key);
 59         else
 60                 static_key_enable(key);
 61 }
 62 
 63 static void invert_keys(struct test_key *keys, int size)
 64 {
 65         struct static_key *previous = NULL;
 66         int i;
 67 
 68         for (i = 0; i < size; i++) {
 69                 if (previous != keys[i].key) {
 70                         invert_key(keys[i].key);
 71                         previous = keys[i].key;
 72                 }
 73         }
 74 }
 75 
 76 static int verify_keys(struct test_key *keys, int size, bool invert)
 77 {
 78         int i;
 79         bool ret, init;
 80 
 81         for (i = 0; i < size; i++) {
 82                 ret = static_key_enabled(keys[i].key);
 83                 init = keys[i].init_state;
 84                 if (ret != (invert ? !init : init))
 85                         return -EINVAL;
 86                 ret = keys[i].test_key();
 87                 if (static_key_enabled(keys[i].key)) {
 88                         if (!ret)
 89                                 return -EINVAL;
 90                 } else {
 91                         if (ret)
 92                                 return -EINVAL;
 93                 }
 94         }
 95         return 0;
 96 }
 97 
 98 test_key_func(old_true_key, static_key_true)
 99 test_key_func(old_false_key, static_key_false)
100 test_key_func(true_key, static_branch_likely)
101 test_key_func(true_key, static_branch_unlikely)
102 test_key_func(false_key, static_branch_likely)
103 test_key_func(false_key, static_branch_unlikely)
104 test_key_func(base_old_true_key, static_key_true)
105 test_key_func(base_inv_old_true_key, static_key_true)
106 test_key_func(base_old_false_key, static_key_false)
107 test_key_func(base_inv_old_false_key, static_key_false)
108 test_key_func(base_true_key, static_branch_likely)
109 test_key_func(base_true_key, static_branch_unlikely)
110 test_key_func(base_inv_true_key, static_branch_likely)
111 test_key_func(base_inv_true_key, static_branch_unlikely)
112 test_key_func(base_false_key, static_branch_likely)
113 test_key_func(base_false_key, static_branch_unlikely)
114 test_key_func(base_inv_false_key, static_branch_likely)
115 test_key_func(base_inv_false_key, static_branch_unlikely)
116 
117 static int __init test_static_key_init(void)
118 {
119         int ret;
120         int size;
121 
122         struct test_key static_key_tests[] = {
123                 /* internal keys - old keys */
124                 {
125                         .init_state     = true,
126                         .key            = &old_true_key,
127                         .test_key       = &old_true_key_static_key_true,
128                 },
129                 {
130                         .init_state     = false,
131                         .key            = &old_false_key,
132                         .test_key       = &old_false_key_static_key_false,
133                 },
134                 /* internal keys - new keys */
135                 {
136                         .init_state     = true,
137                         .key            = &true_key.key,
138                         .test_key       = &true_key_static_branch_likely,
139                 },
140                 {
141                         .init_state     = true,
142                         .key            = &true_key.key,
143                         .test_key       = &true_key_static_branch_unlikely,
144                 },
145                 {
146                         .init_state     = false,
147                         .key            = &false_key.key,
148                         .test_key       = &false_key_static_branch_likely,
149                 },
150                 {
151                         .init_state     = false,
152                         .key            = &false_key.key,
153                         .test_key       = &false_key_static_branch_unlikely,
154                 },
155                 /* external keys - old keys */
156                 {
157                         .init_state     = true,
158                         .key            = &base_old_true_key,
159                         .test_key       = &base_old_true_key_static_key_true,
160                 },
161                 {
162                         .init_state     = false,
163                         .key            = &base_inv_old_true_key,
164                         .test_key       = &base_inv_old_true_key_static_key_true,
165                 },
166                 {
167                         .init_state     = false,
168                         .key            = &base_old_false_key,
169                         .test_key       = &base_old_false_key_static_key_false,
170                 },
171                 {
172                         .init_state     = true,
173                         .key            = &base_inv_old_false_key,
174                         .test_key       = &base_inv_old_false_key_static_key_false,
175                 },
176                 /* external keys - new keys */
177                 {
178                         .init_state     = true,
179                         .key            = &base_true_key.key,
180                         .test_key       = &base_true_key_static_branch_likely,
181                 },
182                 {
183                         .init_state     = true,
184                         .key            = &base_true_key.key,
185                         .test_key       = &base_true_key_static_branch_unlikely,
186                 },
187                 {
188                         .init_state     = false,
189                         .key            = &base_inv_true_key.key,
190                         .test_key       = &base_inv_true_key_static_branch_likely,
191                 },
192                 {
193                         .init_state     = false,
194                         .key            = &base_inv_true_key.key,
195                         .test_key       = &base_inv_true_key_static_branch_unlikely,
196                 },
197                 {
198                         .init_state     = false,
199                         .key            = &base_false_key.key,
200                         .test_key       = &base_false_key_static_branch_likely,
201                 },
202                 {
203                         .init_state     = false,
204                         .key            = &base_false_key.key,
205                         .test_key       = &base_false_key_static_branch_unlikely,
206                 },
207                 {
208                         .init_state     = true,
209                         .key            = &base_inv_false_key.key,
210                         .test_key       = &base_inv_false_key_static_branch_likely,
211                 },
212                 {
213                         .init_state     = true,
214                         .key            = &base_inv_false_key.key,
215                         .test_key       = &base_inv_false_key_static_branch_unlikely,
216                 },
217         };
218 
219         size = ARRAY_SIZE(static_key_tests);
220 
221         ret = verify_keys(static_key_tests, size, false);
222         if (ret)
223                 goto out;
224 
225         invert_keys(static_key_tests, size);
226         ret = verify_keys(static_key_tests, size, true);
227         if (ret)
228                 goto out;
229 
230         invert_keys(static_key_tests, size);
231         ret = verify_keys(static_key_tests, size, false);
232         if (ret)
233                 goto out;
234         return 0;
235 out:
236         return ret;
237 }
238 
239 static void __exit test_static_key_exit(void)
240 {
241 }
242 
243 module_init(test_static_key_init);
244 module_exit(test_static_key_exit);
245 
246 MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
247 MODULE_LICENSE("GPL");
248 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us