File Index
Files and directories
Sign in
FILE

percpu_test.c

File preview with syntax highlighting.

linux-6.19.14/lib/percpu_test.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2#include <linux/limits.h>
  3#include <linux/module.h>
  4
  5/* validate @native and @pcp counter values match @expected */
  6#define CHECK(native, pcp, expected)                                    \
  7	do {                                                            \
  8		WARN((native) != (expected),                            \
  9		     "raw %ld (0x%lx) != expected %lld (0x%llx)",	\
 10		     (native), (native),				\
 11		     (long long)(expected), (long long)(expected));	\
 12		WARN(__this_cpu_read(pcp) != (expected),                \
 13		     "pcp %ld (0x%lx) != expected %lld (0x%llx)",	\
 14		     __this_cpu_read(pcp), __this_cpu_read(pcp),	\
 15		     (long long)(expected), (long long)(expected));	\
 16	} while (0)
 17
 18static DEFINE_PER_CPU(long, long_counter);
 19static DEFINE_PER_CPU(unsigned long, ulong_counter);
 20
 21static int __init percpu_test_init(void)
 22{
 23	/*
 24	 * volatile prevents compiler from optimizing it uses, otherwise the
 25	 * +ul_one/-ul_one below would replace with inc/dec instructions.
 26	 */
 27	volatile unsigned int ui_one = 1;
 28	unsigned long long ull = 0;
 29	unsigned long ul = 0;
 30	long l = 0;
 31
 32	pr_info("percpu test start\n");
 33
 34	preempt_disable();
 35
 36	l += -1;
 37	__this_cpu_add(long_counter, -1);
 38	CHECK(l, long_counter, -1);
 39
 40	l += 1;
 41	__this_cpu_add(long_counter, 1);
 42	CHECK(l, long_counter, 0);
 43
 44	ul = 0;
 45	__this_cpu_write(ulong_counter, 0);
 46
 47	ul += 1UL;
 48	__this_cpu_add(ulong_counter, 1UL);
 49	CHECK(ul, ulong_counter, 1);
 50
 51	ul += -1UL;
 52	__this_cpu_add(ulong_counter, -1UL);
 53	CHECK(ul, ulong_counter, 0);
 54
 55	ul += -(unsigned long)1;
 56	__this_cpu_add(ulong_counter, -(unsigned long)1);
 57	CHECK(ul, ulong_counter, -1);
 58
 59	ul = 0;
 60	__this_cpu_write(ulong_counter, 0);
 61
 62	ul -= 1;
 63	__this_cpu_dec(ulong_counter);
 64	CHECK(ul, ulong_counter, -1);
 65	CHECK(ul, ulong_counter, ULONG_MAX);
 66
 67	l += -ui_one;
 68	__this_cpu_add(long_counter, -ui_one);
 69	CHECK(l, long_counter, 0xffffffff);
 70
 71	l += ui_one;
 72	__this_cpu_add(long_counter, ui_one);
 73	CHECK(l, long_counter, (long)0x100000000LL);
 74
 75
 76	l = 0;
 77	__this_cpu_write(long_counter, 0);
 78
 79	l -= ui_one;
 80	__this_cpu_sub(long_counter, ui_one);
 81	CHECK(l, long_counter, -1);
 82
 83	l = 0;
 84	__this_cpu_write(long_counter, 0);
 85
 86	l += ui_one;
 87	__this_cpu_add(long_counter, ui_one);
 88	CHECK(l, long_counter, 1);
 89
 90	l += -ui_one;
 91	__this_cpu_add(long_counter, -ui_one);
 92	CHECK(l, long_counter, (long)0x100000000LL);
 93
 94	l = 0;
 95	__this_cpu_write(long_counter, 0);
 96
 97	l -= ui_one;
 98	this_cpu_sub(long_counter, ui_one);
 99	CHECK(l, long_counter, -1);
100	CHECK(l, long_counter, ULONG_MAX);
101
102	ul = 0;
103	__this_cpu_write(ulong_counter, 0);
104
105	ul += ui_one;
106	__this_cpu_add(ulong_counter, ui_one);
107	CHECK(ul, ulong_counter, 1);
108
109	ul = 0;
110	__this_cpu_write(ulong_counter, 0);
111
112	ul -= ui_one;
113	__this_cpu_sub(ulong_counter, ui_one);
114	CHECK(ul, ulong_counter, -1);
115	CHECK(ul, ulong_counter, ULONG_MAX);
116
117	ul = ull = 0;
118	__this_cpu_write(ulong_counter, 0);
119
120	ul = ull += UINT_MAX;
121	__this_cpu_add(ulong_counter, ull);
122	CHECK(ul, ulong_counter, UINT_MAX);
123
124	ul = 3;
125	__this_cpu_write(ulong_counter, 3);
126
127	ul = this_cpu_sub_return(ulong_counter, ui_one);
128	CHECK(ul, ulong_counter, 2);
129
130	ul = __this_cpu_sub_return(ulong_counter, ui_one);
131	CHECK(ul, ulong_counter, 1);
132
133	preempt_enable();
134
135	pr_info("percpu test done\n");
136	return -EAGAIN;  /* Fail will directly unload the module */
137}
138
139static void __exit percpu_test_exit(void)
140{
141}
142
143module_init(percpu_test_init)
144module_exit(percpu_test_exit)
145
146MODULE_LICENSE("GPL");
147MODULE_AUTHOR("Greg Thelen");
148MODULE_DESCRIPTION("percpu operations test");
~/ Read-only file preview.