Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Kernel module for testing static keys.
0004  *
0005  * Copyright 2015 Akamai Technologies Inc. All Rights Reserved
0006  *
0007  * Authors:
0008  *      Jason Baron       <jbaron@akamai.com>
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/jump_label.h>
0013 
0014 /* old keys */
0015 struct static_key old_true_key  = STATIC_KEY_INIT_TRUE;
0016 struct static_key old_false_key = STATIC_KEY_INIT_FALSE;
0017 
0018 /* new api */
0019 DEFINE_STATIC_KEY_TRUE(true_key);
0020 DEFINE_STATIC_KEY_FALSE(false_key);
0021 
0022 /* external */
0023 extern struct static_key base_old_true_key;
0024 extern struct static_key base_inv_old_true_key;
0025 extern struct static_key base_old_false_key;
0026 extern struct static_key base_inv_old_false_key;
0027 
0028 /* new api */
0029 extern struct static_key_true base_true_key;
0030 extern struct static_key_true base_inv_true_key;
0031 extern struct static_key_false base_false_key;
0032 extern struct static_key_false base_inv_false_key;
0033 
0034 
0035 struct test_key {
0036     bool            init_state;
0037     struct static_key   *key;
0038     bool            (*test_key)(void);
0039 };
0040 
0041 #define test_key_func(key, branch)  \
0042 static bool key ## _ ## branch(void)    \
0043 {                   \
0044     return branch(&key);        \
0045 }
0046 
0047 static void invert_key(struct static_key *key)
0048 {
0049     if (static_key_enabled(key))
0050         static_key_disable(key);
0051     else
0052         static_key_enable(key);
0053 }
0054 
0055 static void invert_keys(struct test_key *keys, int size)
0056 {
0057     struct static_key *previous = NULL;
0058     int i;
0059 
0060     for (i = 0; i < size; i++) {
0061         if (previous != keys[i].key) {
0062             invert_key(keys[i].key);
0063             previous = keys[i].key;
0064         }
0065     }
0066 }
0067 
0068 static int verify_keys(struct test_key *keys, int size, bool invert)
0069 {
0070     int i;
0071     bool ret, init;
0072 
0073     for (i = 0; i < size; i++) {
0074         ret = static_key_enabled(keys[i].key);
0075         init = keys[i].init_state;
0076         if (ret != (invert ? !init : init))
0077             return -EINVAL;
0078         ret = keys[i].test_key();
0079         if (static_key_enabled(keys[i].key)) {
0080             if (!ret)
0081                 return -EINVAL;
0082         } else {
0083             if (ret)
0084                 return -EINVAL;
0085         }
0086     }
0087     return 0;
0088 }
0089 
0090 test_key_func(old_true_key, static_key_true)
0091 test_key_func(old_false_key, static_key_false)
0092 test_key_func(true_key, static_branch_likely)
0093 test_key_func(true_key, static_branch_unlikely)
0094 test_key_func(false_key, static_branch_likely)
0095 test_key_func(false_key, static_branch_unlikely)
0096 test_key_func(base_old_true_key, static_key_true)
0097 test_key_func(base_inv_old_true_key, static_key_true)
0098 test_key_func(base_old_false_key, static_key_false)
0099 test_key_func(base_inv_old_false_key, static_key_false)
0100 test_key_func(base_true_key, static_branch_likely)
0101 test_key_func(base_true_key, static_branch_unlikely)
0102 test_key_func(base_inv_true_key, static_branch_likely)
0103 test_key_func(base_inv_true_key, static_branch_unlikely)
0104 test_key_func(base_false_key, static_branch_likely)
0105 test_key_func(base_false_key, static_branch_unlikely)
0106 test_key_func(base_inv_false_key, static_branch_likely)
0107 test_key_func(base_inv_false_key, static_branch_unlikely)
0108 
0109 static int __init test_static_key_init(void)
0110 {
0111     int ret;
0112     int size;
0113 
0114     struct test_key static_key_tests[] = {
0115         /* internal keys - old keys */
0116         {
0117             .init_state = true,
0118             .key        = &old_true_key,
0119             .test_key   = &old_true_key_static_key_true,
0120         },
0121         {
0122             .init_state = false,
0123             .key        = &old_false_key,
0124             .test_key   = &old_false_key_static_key_false,
0125         },
0126         /* internal keys - new keys */
0127         {
0128             .init_state = true,
0129             .key        = &true_key.key,
0130             .test_key   = &true_key_static_branch_likely,
0131         },
0132         {
0133             .init_state = true,
0134             .key        = &true_key.key,
0135             .test_key   = &true_key_static_branch_unlikely,
0136         },
0137         {
0138             .init_state = false,
0139             .key        = &false_key.key,
0140             .test_key   = &false_key_static_branch_likely,
0141         },
0142         {
0143             .init_state = false,
0144             .key        = &false_key.key,
0145             .test_key   = &false_key_static_branch_unlikely,
0146         },
0147         /* external keys - old keys */
0148         {
0149             .init_state = true,
0150             .key        = &base_old_true_key,
0151             .test_key   = &base_old_true_key_static_key_true,
0152         },
0153         {
0154             .init_state = false,
0155             .key        = &base_inv_old_true_key,
0156             .test_key   = &base_inv_old_true_key_static_key_true,
0157         },
0158         {
0159             .init_state = false,
0160             .key        = &base_old_false_key,
0161             .test_key   = &base_old_false_key_static_key_false,
0162         },
0163         {
0164             .init_state = true,
0165             .key        = &base_inv_old_false_key,
0166             .test_key   = &base_inv_old_false_key_static_key_false,
0167         },
0168         /* external keys - new keys */
0169         {
0170             .init_state = true,
0171             .key        = &base_true_key.key,
0172             .test_key   = &base_true_key_static_branch_likely,
0173         },
0174         {
0175             .init_state = true,
0176             .key        = &base_true_key.key,
0177             .test_key   = &base_true_key_static_branch_unlikely,
0178         },
0179         {
0180             .init_state = false,
0181             .key        = &base_inv_true_key.key,
0182             .test_key   = &base_inv_true_key_static_branch_likely,
0183         },
0184         {
0185             .init_state = false,
0186             .key        = &base_inv_true_key.key,
0187             .test_key   = &base_inv_true_key_static_branch_unlikely,
0188         },
0189         {
0190             .init_state = false,
0191             .key        = &base_false_key.key,
0192             .test_key   = &base_false_key_static_branch_likely,
0193         },
0194         {
0195             .init_state = false,
0196             .key        = &base_false_key.key,
0197             .test_key   = &base_false_key_static_branch_unlikely,
0198         },
0199         {
0200             .init_state = true,
0201             .key        = &base_inv_false_key.key,
0202             .test_key   = &base_inv_false_key_static_branch_likely,
0203         },
0204         {
0205             .init_state = true,
0206             .key        = &base_inv_false_key.key,
0207             .test_key   = &base_inv_false_key_static_branch_unlikely,
0208         },
0209     };
0210 
0211     size = ARRAY_SIZE(static_key_tests);
0212 
0213     ret = verify_keys(static_key_tests, size, false);
0214     if (ret)
0215         goto out;
0216 
0217     invert_keys(static_key_tests, size);
0218     ret = verify_keys(static_key_tests, size, true);
0219     if (ret)
0220         goto out;
0221 
0222     invert_keys(static_key_tests, size);
0223     ret = verify_keys(static_key_tests, size, false);
0224     if (ret)
0225         goto out;
0226     return 0;
0227 out:
0228     return ret;
0229 }
0230 
0231 static void __exit test_static_key_exit(void)
0232 {
0233 }
0234 
0235 module_init(test_static_key_init);
0236 module_exit(test_static_key_exit);
0237 
0238 MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
0239 MODULE_LICENSE("GPL");