root/lib/test_static_keys.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. invert_key
  2. invert_keys
  3. verify_keys
  4. test_key_func
  5. test_static_key_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Kernel module for testing static keys.
   4  *
   5  * Copyright 2015 Akamai Technologies Inc. All Rights Reserved
   6  *
   7  * Authors:
   8  *      Jason Baron       <jbaron@akamai.com>
   9  */
  10 
  11 #include <linux/module.h>
  12 #include <linux/jump_label.h>
  13 
  14 /* old keys */
  15 struct static_key old_true_key  = STATIC_KEY_INIT_TRUE;
  16 struct static_key old_false_key = STATIC_KEY_INIT_FALSE;
  17 
  18 /* new api */
  19 DEFINE_STATIC_KEY_TRUE(true_key);
  20 DEFINE_STATIC_KEY_FALSE(false_key);
  21 
  22 /* external */
  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;
  27 
  28 /* new api */
  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;
  33 
  34 
  35 struct test_key {
  36         bool                    init_state;
  37         struct static_key       *key;
  38         bool                    (*test_key)(void);
  39 };
  40 
  41 #define test_key_func(key, branch)      \
  42 static bool key ## _ ## branch(void)    \
  43 {                                       \
  44         return branch(&key);            \
  45 }
  46 
  47 static void invert_key(struct static_key *key)
  48 {
  49         if (static_key_enabled(key))
  50                 static_key_disable(key);
  51         else
  52                 static_key_enable(key);
  53 }
  54 
  55 static void invert_keys(struct test_key *keys, int size)
  56 {
  57         struct static_key *previous = NULL;
  58         int i;
  59 
  60         for (i = 0; i < size; i++) {
  61                 if (previous != keys[i].key) {
  62                         invert_key(keys[i].key);
  63                         previous = keys[i].key;
  64                 }
  65         }
  66 }
  67 
  68 static int verify_keys(struct test_key *keys, int size, bool invert)
  69 {
  70         int i;
  71         bool ret, init;
  72 
  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))
  77                         return -EINVAL;
  78                 ret = keys[i].test_key();
  79                 if (static_key_enabled(keys[i].key)) {
  80                         if (!ret)
  81                                 return -EINVAL;
  82                 } else {
  83                         if (ret)
  84                                 return -EINVAL;
  85                 }
  86         }
  87         return 0;
  88 }
  89 
  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)
 108 
 109 static int __init test_static_key_init(void)
 110 {
 111         int ret;
 112         int size;
 113 
 114         struct test_key static_key_tests[] = {
 115                 /* internal keys - old keys */
 116                 {
 117                         .init_state     = true,
 118                         .key            = &old_true_key,
 119                         .test_key       = &old_true_key_static_key_true,
 120                 },
 121                 {
 122                         .init_state     = false,
 123                         .key            = &old_false_key,
 124                         .test_key       = &old_false_key_static_key_false,
 125                 },
 126                 /* internal keys - new keys */
 127                 {
 128                         .init_state     = true,
 129                         .key            = &true_key.key,
 130                         .test_key       = &true_key_static_branch_likely,
 131                 },
 132                 {
 133                         .init_state     = true,
 134                         .key            = &true_key.key,
 135                         .test_key       = &true_key_static_branch_unlikely,
 136                 },
 137                 {
 138                         .init_state     = false,
 139                         .key            = &false_key.key,
 140                         .test_key       = &false_key_static_branch_likely,
 141                 },
 142                 {
 143                         .init_state     = false,
 144                         .key            = &false_key.key,
 145                         .test_key       = &false_key_static_branch_unlikely,
 146                 },
 147                 /* external keys - old keys */
 148                 {
 149                         .init_state     = true,
 150                         .key            = &base_old_true_key,
 151                         .test_key       = &base_old_true_key_static_key_true,
 152                 },
 153                 {
 154                         .init_state     = false,
 155                         .key            = &base_inv_old_true_key,
 156                         .test_key       = &base_inv_old_true_key_static_key_true,
 157                 },
 158                 {
 159                         .init_state     = false,
 160                         .key            = &base_old_false_key,
 161                         .test_key       = &base_old_false_key_static_key_false,
 162                 },
 163                 {
 164                         .init_state     = true,
 165                         .key            = &base_inv_old_false_key,
 166                         .test_key       = &base_inv_old_false_key_static_key_false,
 167                 },
 168                 /* external keys - new keys */
 169                 {
 170                         .init_state     = true,
 171                         .key            = &base_true_key.key,
 172                         .test_key       = &base_true_key_static_branch_likely,
 173                 },
 174                 {
 175                         .init_state     = true,
 176                         .key            = &base_true_key.key,
 177                         .test_key       = &base_true_key_static_branch_unlikely,
 178                 },
 179                 {
 180                         .init_state     = false,
 181                         .key            = &base_inv_true_key.key,
 182                         .test_key       = &base_inv_true_key_static_branch_likely,
 183                 },
 184                 {
 185                         .init_state     = false,
 186                         .key            = &base_inv_true_key.key,
 187                         .test_key       = &base_inv_true_key_static_branch_unlikely,
 188                 },
 189                 {
 190                         .init_state     = false,
 191                         .key            = &base_false_key.key,
 192                         .test_key       = &base_false_key_static_branch_likely,
 193                 },
 194                 {
 195                         .init_state     = false,
 196                         .key            = &base_false_key.key,
 197                         .test_key       = &base_false_key_static_branch_unlikely,
 198                 },
 199                 {
 200                         .init_state     = true,
 201                         .key            = &base_inv_false_key.key,
 202                         .test_key       = &base_inv_false_key_static_branch_likely,
 203                 },
 204                 {
 205                         .init_state     = true,
 206                         .key            = &base_inv_false_key.key,
 207                         .test_key       = &base_inv_false_key_static_branch_unlikely,
 208                 },
 209         };
 210 
 211         size = ARRAY_SIZE(static_key_tests);
 212 
 213         ret = verify_keys(static_key_tests, size, false);
 214         if (ret)
 215                 goto out;
 216 
 217         invert_keys(static_key_tests, size);
 218         ret = verify_keys(static_key_tests, size, true);
 219         if (ret)
 220                 goto out;
 221 
 222         invert_keys(static_key_tests, size);
 223         ret = verify_keys(static_key_tests, size, false);
 224         if (ret)
 225                 goto out;
 226         return 0;
 227 out:
 228         return ret;
 229 }
 230 
 231 static void __exit test_static_key_exit(void)
 232 {
 233 }
 234 
 235 module_init(test_static_key_init);
 236 module_exit(test_static_key_exit);
 237 
 238 MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
 239 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */