1 #ifndef __TOOLS_LINUX_PERCPU_H
2 #define __TOOLS_LINUX_PERCPU_H
6 #define free_percpu(percpu) free(percpu)
8 #define __alloc_percpu_gfp(size, align, gfp) calloc(1, size)
9 #define __alloc_percpu(size, align) calloc(1, size)
11 #define alloc_percpu_gfp(type, gfp) \
12 (typeof(type) __percpu *)__alloc_percpu_gfp(sizeof(type), \
13 __alignof__(type), gfp)
14 #define alloc_percpu(type) \
15 (typeof(type) __percpu *)__alloc_percpu(sizeof(type), \
18 #define __verify_pcpu_ptr(ptr)
20 #define per_cpu_ptr(ptr, cpu) (ptr)
21 #define raw_cpu_ptr(ptr) (ptr)
22 #define this_cpu_ptr(ptr) raw_cpu_ptr(ptr)
24 #define __pcpu_size_call_return(stem, variable) \
26 typeof(variable) pscr_ret__; \
27 __verify_pcpu_ptr(&(variable)); \
28 switch(sizeof(variable)) { \
29 case 1: pscr_ret__ = stem##1(variable); break; \
30 case 2: pscr_ret__ = stem##2(variable); break; \
31 case 4: pscr_ret__ = stem##4(variable); break; \
32 case 8: pscr_ret__ = stem##8(variable); break; \
34 __bad_size_call_parameter(); break; \
39 #define __pcpu_size_call_return2(stem, variable, ...) \
41 typeof(variable) pscr2_ret__; \
42 __verify_pcpu_ptr(&(variable)); \
43 switch(sizeof(variable)) { \
44 case 1: pscr2_ret__ = stem##1(variable, __VA_ARGS__); break; \
45 case 2: pscr2_ret__ = stem##2(variable, __VA_ARGS__); break; \
46 case 4: pscr2_ret__ = stem##4(variable, __VA_ARGS__); break; \
47 case 8: pscr2_ret__ = stem##8(variable, __VA_ARGS__); break; \
49 __bad_size_call_parameter(); break; \
55 * Special handling for cmpxchg_double. cmpxchg_double is passed two
56 * percpu variables. The first has to be aligned to a double word
57 * boundary and the second has to follow directly thereafter.
58 * We enforce this on all architectures even if they don't support
59 * a double cmpxchg instruction, since it's a cheap requirement, and it
60 * avoids breaking the requirement for architectures with the instruction.
62 #define __pcpu_double_call_return_bool(stem, pcp1, pcp2, ...) \
65 __verify_pcpu_ptr(&(pcp1)); \
66 BUILD_BUG_ON(sizeof(pcp1) != sizeof(pcp2)); \
67 VM_BUG_ON((unsigned long)(&(pcp1)) % (2 * sizeof(pcp1))); \
68 VM_BUG_ON((unsigned long)(&(pcp2)) != \
69 (unsigned long)(&(pcp1)) + sizeof(pcp1)); \
70 switch(sizeof(pcp1)) { \
71 case 1: pdcrb_ret__ = stem##1(pcp1, pcp2, __VA_ARGS__); break; \
72 case 2: pdcrb_ret__ = stem##2(pcp1, pcp2, __VA_ARGS__); break; \
73 case 4: pdcrb_ret__ = stem##4(pcp1, pcp2, __VA_ARGS__); break; \
74 case 8: pdcrb_ret__ = stem##8(pcp1, pcp2, __VA_ARGS__); break; \
76 __bad_size_call_parameter(); break; \
81 #define __pcpu_size_call(stem, variable, ...) \
83 __verify_pcpu_ptr(&(variable)); \
84 switch(sizeof(variable)) { \
85 case 1: stem##1(variable, __VA_ARGS__);break; \
86 case 2: stem##2(variable, __VA_ARGS__);break; \
87 case 4: stem##4(variable, __VA_ARGS__);break; \
88 case 8: stem##8(variable, __VA_ARGS__);break; \
90 __bad_size_call_parameter();break; \
94 #define raw_cpu_read(pcp) __pcpu_size_call_return(raw_cpu_read_, pcp)
95 #define raw_cpu_write(pcp, val) __pcpu_size_call(raw_cpu_write_, pcp, val)
96 #define raw_cpu_add(pcp, val) __pcpu_size_call(raw_cpu_add_, pcp, val)
97 #define raw_cpu_and(pcp, val) __pcpu_size_call(raw_cpu_and_, pcp, val)
98 #define raw_cpu_or(pcp, val) __pcpu_size_call(raw_cpu_or_, pcp, val)
99 #define raw_cpu_add_return(pcp, val) __pcpu_size_call_return2(raw_cpu_add_return_, pcp, val)
100 #define raw_cpu_xchg(pcp, nval) __pcpu_size_call_return2(raw_cpu_xchg_, pcp, nval)
101 #define raw_cpu_cmpxchg(pcp, oval, nval) \
102 __pcpu_size_call_return2(raw_cpu_cmpxchg_, pcp, oval, nval)
103 #define raw_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \
104 __pcpu_double_call_return_bool(raw_cpu_cmpxchg_double_, pcp1, pcp2, oval1, oval2, nval1, nval2)
106 #define raw_cpu_sub(pcp, val) raw_cpu_add(pcp, -(val))
107 #define raw_cpu_inc(pcp) raw_cpu_add(pcp, 1)
108 #define raw_cpu_dec(pcp) raw_cpu_sub(pcp, 1)
109 #define raw_cpu_sub_return(pcp, val) raw_cpu_add_return(pcp, -(typeof(pcp))(val))
110 #define raw_cpu_inc_return(pcp) raw_cpu_add_return(pcp, 1)
111 #define raw_cpu_dec_return(pcp) raw_cpu_add_return(pcp, -1)
113 #define __this_cpu_read(pcp) \
118 #define __this_cpu_write(pcp, val) \
120 raw_cpu_write(pcp, val); \
123 #define __this_cpu_add(pcp, val) \
125 raw_cpu_add(pcp, val); \
128 #define __this_cpu_and(pcp, val) \
130 raw_cpu_and(pcp, val); \
133 #define __this_cpu_or(pcp, val) \
135 raw_cpu_or(pcp, val); \
138 #define __this_cpu_add_return(pcp, val) \
140 raw_cpu_add_return(pcp, val); \
143 #define __this_cpu_xchg(pcp, nval) \
145 raw_cpu_xchg(pcp, nval); \
148 #define __this_cpu_cmpxchg(pcp, oval, nval) \
150 raw_cpu_cmpxchg(pcp, oval, nval); \
153 #define __this_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \
154 raw_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2); \
157 #define __this_cpu_sub(pcp, val) __this_cpu_add(pcp, -(typeof(pcp))(val))
158 #define __this_cpu_inc(pcp) __this_cpu_add(pcp, 1)
159 #define __this_cpu_dec(pcp) __this_cpu_sub(pcp, 1)
160 #define __this_cpu_sub_return(pcp, val) __this_cpu_add_return(pcp, -(typeof(pcp))(val))
161 #define __this_cpu_inc_return(pcp) __this_cpu_add_return(pcp, 1)
162 #define __this_cpu_dec_return(pcp) __this_cpu_add_return(pcp, -1)
164 #define this_cpu_read(pcp) ((pcp))
165 #define this_cpu_write(pcp, val) ((pcp) = val)
166 #define this_cpu_add(pcp, val) ((pcp) += val)
167 #define this_cpu_and(pcp, val) ((pcp) &= val)
168 #define this_cpu_or(pcp, val) ((pcp) |= val)
169 #define this_cpu_add_return(pcp, val) ((pcp) += val)
170 #define this_cpu_xchg(pcp, nval) \
172 typeof(pcp) _r = (pcp); \
177 #define this_cpu_cmpxchg(pcp, oval, nval) \
178 __pcpu_size_call_return2(this_cpu_cmpxchg_, pcp, oval, nval)
179 #define this_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \
180 __pcpu_double_call_return_bool(this_cpu_cmpxchg_double_, pcp1, pcp2, oval1, oval2, nval1, nval2)
182 #define this_cpu_sub(pcp, val) this_cpu_add(pcp, -(typeof(pcp))(val))
183 #define this_cpu_inc(pcp) this_cpu_add(pcp, 1)
184 #define this_cpu_dec(pcp) this_cpu_sub(pcp, 1)
185 #define this_cpu_sub_return(pcp, val) this_cpu_add_return(pcp, -(typeof(pcp))(val))
186 #define this_cpu_inc_return(pcp) this_cpu_add_return(pcp, 1)
187 #define this_cpu_dec_return(pcp) this_cpu_add_return(pcp, -1)
189 #endif /* __TOOLS_LINUX_PERCPU_H */