0001
0002 #include <linux/module.h>
0003
0004
0005 #define CHECK(native, pcp, expected) \
0006 do { \
0007 WARN((native) != (expected), \
0008 "raw %ld (0x%lx) != expected %lld (0x%llx)", \
0009 (native), (native), \
0010 (long long)(expected), (long long)(expected)); \
0011 WARN(__this_cpu_read(pcp) != (expected), \
0012 "pcp %ld (0x%lx) != expected %lld (0x%llx)", \
0013 __this_cpu_read(pcp), __this_cpu_read(pcp), \
0014 (long long)(expected), (long long)(expected)); \
0015 } while (0)
0016
0017 static DEFINE_PER_CPU(long, long_counter);
0018 static DEFINE_PER_CPU(unsigned long, ulong_counter);
0019
0020 static int __init percpu_test_init(void)
0021 {
0022
0023
0024
0025
0026 volatile unsigned int ui_one = 1;
0027 long l = 0;
0028 unsigned long ul = 0;
0029
0030 pr_info("percpu test start\n");
0031
0032 preempt_disable();
0033
0034 l += -1;
0035 __this_cpu_add(long_counter, -1);
0036 CHECK(l, long_counter, -1);
0037
0038 l += 1;
0039 __this_cpu_add(long_counter, 1);
0040 CHECK(l, long_counter, 0);
0041
0042 ul = 0;
0043 __this_cpu_write(ulong_counter, 0);
0044
0045 ul += 1UL;
0046 __this_cpu_add(ulong_counter, 1UL);
0047 CHECK(ul, ulong_counter, 1);
0048
0049 ul += -1UL;
0050 __this_cpu_add(ulong_counter, -1UL);
0051 CHECK(ul, ulong_counter, 0);
0052
0053 ul += -(unsigned long)1;
0054 __this_cpu_add(ulong_counter, -(unsigned long)1);
0055 CHECK(ul, ulong_counter, -1);
0056
0057 ul = 0;
0058 __this_cpu_write(ulong_counter, 0);
0059
0060 ul -= 1;
0061 __this_cpu_dec(ulong_counter);
0062 CHECK(ul, ulong_counter, -1);
0063 CHECK(ul, ulong_counter, ULONG_MAX);
0064
0065 l += -ui_one;
0066 __this_cpu_add(long_counter, -ui_one);
0067 CHECK(l, long_counter, 0xffffffff);
0068
0069 l += ui_one;
0070 __this_cpu_add(long_counter, ui_one);
0071 CHECK(l, long_counter, (long)0x100000000LL);
0072
0073
0074 l = 0;
0075 __this_cpu_write(long_counter, 0);
0076
0077 l -= ui_one;
0078 __this_cpu_sub(long_counter, ui_one);
0079 CHECK(l, long_counter, -1);
0080
0081 l = 0;
0082 __this_cpu_write(long_counter, 0);
0083
0084 l += ui_one;
0085 __this_cpu_add(long_counter, ui_one);
0086 CHECK(l, long_counter, 1);
0087
0088 l += -ui_one;
0089 __this_cpu_add(long_counter, -ui_one);
0090 CHECK(l, long_counter, (long)0x100000000LL);
0091
0092 l = 0;
0093 __this_cpu_write(long_counter, 0);
0094
0095 l -= ui_one;
0096 this_cpu_sub(long_counter, ui_one);
0097 CHECK(l, long_counter, -1);
0098 CHECK(l, long_counter, ULONG_MAX);
0099
0100 ul = 0;
0101 __this_cpu_write(ulong_counter, 0);
0102
0103 ul += ui_one;
0104 __this_cpu_add(ulong_counter, ui_one);
0105 CHECK(ul, ulong_counter, 1);
0106
0107 ul = 0;
0108 __this_cpu_write(ulong_counter, 0);
0109
0110 ul -= ui_one;
0111 __this_cpu_sub(ulong_counter, ui_one);
0112 CHECK(ul, ulong_counter, -1);
0113 CHECK(ul, ulong_counter, ULONG_MAX);
0114
0115 ul = 3;
0116 __this_cpu_write(ulong_counter, 3);
0117
0118 ul = this_cpu_sub_return(ulong_counter, ui_one);
0119 CHECK(ul, ulong_counter, 2);
0120
0121 ul = __this_cpu_sub_return(ulong_counter, ui_one);
0122 CHECK(ul, ulong_counter, 1);
0123
0124 preempt_enable();
0125
0126 pr_info("percpu test done\n");
0127 return -EAGAIN;
0128 }
0129
0130 static void __exit percpu_test_exit(void)
0131 {
0132 }
0133
0134 module_init(percpu_test_init)
0135 module_exit(percpu_test_exit)
0136
0137 MODULE_LICENSE("GPL");
0138 MODULE_AUTHOR("Greg Thelen");
0139 MODULE_DESCRIPTION("percpu operations test");