Linux Audio

Check our new training course

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