Blame view

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