aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-generic
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-14 14:46:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-14 14:46:25 -0400
commitb6daa51b9a6a02a644dcf6b880fd50c1f70ec07f (patch)
tree745ebeefb8f4225460774ef0037ca2f9022d4a4a /include/asm-generic
parentf96ed2612260a8a415512eed4fe3f5c77247d4a1 (diff)
parent9b7396624a7b503220d85428654634b60762f2b0 (diff)
Merge branch 'for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
Pull percpu updates from Tejun Heo: - Nick improved generic implementations of percpu operations which modify the variable and return so that they calculate the physical address only once. - percpu_ref percpu <-> atomic mode switching improvements. The patchset was originally posted about a year ago but fell through the crack. - misc non-critical fixes. * 'for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu: mm/percpu.c: fix potential memory leakage for pcpu_embed_first_chunk() mm/percpu.c: correct max_distance calculation for pcpu_embed_first_chunk() percpu: eliminate two sparse warnings percpu: improve generic percpu modify-return implementation percpu-refcount: init ->confirm_switch member properly percpu_ref: allow operation mode switching operations to be called concurrently percpu_ref: restructure operation mode switching percpu_ref: unify staggered atomic switching wait behavior percpu_ref: reorganize __percpu_ref_switch_to_atomic() and relocate percpu_ref_switch_to_atomic() percpu_ref: remove unnecessary RCU grace period for staggered atomic switching confirmation
Diffstat (limited to 'include/asm-generic')
-rw-r--r--include/asm-generic/percpu.h53
1 files changed, 30 insertions, 23 deletions
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index 4d9f233c4ba8..40e887068da2 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -65,6 +65,11 @@ extern void setup_per_cpu_areas(void);
65#define PER_CPU_DEF_ATTRIBUTES 65#define PER_CPU_DEF_ATTRIBUTES
66#endif 66#endif
67 67
68#define raw_cpu_generic_read(pcp) \
69({ \
70 *raw_cpu_ptr(&(pcp)); \
71})
72
68#define raw_cpu_generic_to_op(pcp, val, op) \ 73#define raw_cpu_generic_to_op(pcp, val, op) \
69do { \ 74do { \
70 *raw_cpu_ptr(&(pcp)) op val; \ 75 *raw_cpu_ptr(&(pcp)) op val; \
@@ -72,34 +77,39 @@ do { \
72 77
73#define raw_cpu_generic_add_return(pcp, val) \ 78#define raw_cpu_generic_add_return(pcp, val) \
74({ \ 79({ \
75 raw_cpu_add(pcp, val); \ 80 typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \
76 raw_cpu_read(pcp); \ 81 \
82 *__p += val; \
83 *__p; \
77}) 84})
78 85
79#define raw_cpu_generic_xchg(pcp, nval) \ 86#define raw_cpu_generic_xchg(pcp, nval) \
80({ \ 87({ \
88 typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \
81 typeof(pcp) __ret; \ 89 typeof(pcp) __ret; \
82 __ret = raw_cpu_read(pcp); \ 90 __ret = *__p; \
83 raw_cpu_write(pcp, nval); \ 91 *__p = nval; \
84 __ret; \ 92 __ret; \
85}) 93})
86 94
87#define raw_cpu_generic_cmpxchg(pcp, oval, nval) \ 95#define raw_cpu_generic_cmpxchg(pcp, oval, nval) \
88({ \ 96({ \
97 typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \
89 typeof(pcp) __ret; \ 98 typeof(pcp) __ret; \
90 __ret = raw_cpu_read(pcp); \ 99 __ret = *__p; \
91 if (__ret == (oval)) \ 100 if (__ret == (oval)) \
92 raw_cpu_write(pcp, nval); \ 101 *__p = nval; \
93 __ret; \ 102 __ret; \
94}) 103})
95 104
96#define raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ 105#define raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \
97({ \ 106({ \
107 typeof(&(pcp1)) __p1 = raw_cpu_ptr(&(pcp1)); \
108 typeof(&(pcp2)) __p2 = raw_cpu_ptr(&(pcp2)); \
98 int __ret = 0; \ 109 int __ret = 0; \
99 if (raw_cpu_read(pcp1) == (oval1) && \ 110 if (*__p1 == (oval1) && *__p2 == (oval2)) { \
100 raw_cpu_read(pcp2) == (oval2)) { \ 111 *__p1 = nval1; \
101 raw_cpu_write(pcp1, nval1); \ 112 *__p2 = nval2; \
102 raw_cpu_write(pcp2, nval2); \
103 __ret = 1; \ 113 __ret = 1; \
104 } \ 114 } \
105 (__ret); \ 115 (__ret); \
@@ -109,7 +119,7 @@ do { \
109({ \ 119({ \
110 typeof(pcp) __ret; \ 120 typeof(pcp) __ret; \
111 preempt_disable(); \ 121 preempt_disable(); \
112 __ret = *this_cpu_ptr(&(pcp)); \ 122 __ret = raw_cpu_generic_read(pcp); \
113 preempt_enable(); \ 123 preempt_enable(); \
114 __ret; \ 124 __ret; \
115}) 125})
@@ -118,17 +128,17 @@ do { \
118do { \ 128do { \
119 unsigned long __flags; \ 129 unsigned long __flags; \
120 raw_local_irq_save(__flags); \ 130 raw_local_irq_save(__flags); \
121 *raw_cpu_ptr(&(pcp)) op val; \ 131 raw_cpu_generic_to_op(pcp, val, op); \
122 raw_local_irq_restore(__flags); \ 132 raw_local_irq_restore(__flags); \
123} while (0) 133} while (0)
124 134
135
125#define this_cpu_generic_add_return(pcp, val) \ 136#define this_cpu_generic_add_return(pcp, val) \
126({ \ 137({ \
127 typeof(pcp) __ret; \ 138 typeof(pcp) __ret; \
128 unsigned long __flags; \ 139 unsigned long __flags; \
129 raw_local_irq_save(__flags); \ 140 raw_local_irq_save(__flags); \
130 raw_cpu_add(pcp, val); \ 141 __ret = raw_cpu_generic_add_return(pcp, val); \
131 __ret = raw_cpu_read(pcp); \
132 raw_local_irq_restore(__flags); \ 142 raw_local_irq_restore(__flags); \
133 __ret; \ 143 __ret; \
134}) 144})
@@ -138,8 +148,7 @@ do { \
138 typeof(pcp) __ret; \ 148 typeof(pcp) __ret; \
139 unsigned long __flags; \ 149 unsigned long __flags; \
140 raw_local_irq_save(__flags); \ 150 raw_local_irq_save(__flags); \
141 __ret = raw_cpu_read(pcp); \ 151 __ret = raw_cpu_generic_xchg(pcp, nval); \
142 raw_cpu_write(pcp, nval); \
143 raw_local_irq_restore(__flags); \ 152 raw_local_irq_restore(__flags); \
144 __ret; \ 153 __ret; \
145}) 154})
@@ -149,9 +158,7 @@ do { \
149 typeof(pcp) __ret; \ 158 typeof(pcp) __ret; \
150 unsigned long __flags; \ 159 unsigned long __flags; \
151 raw_local_irq_save(__flags); \ 160 raw_local_irq_save(__flags); \
152 __ret = raw_cpu_read(pcp); \ 161 __ret = raw_cpu_generic_cmpxchg(pcp, oval, nval); \
153 if (__ret == (oval)) \
154 raw_cpu_write(pcp, nval); \
155 raw_local_irq_restore(__flags); \ 162 raw_local_irq_restore(__flags); \
156 __ret; \ 163 __ret; \
157}) 164})
@@ -168,16 +175,16 @@ do { \
168}) 175})
169 176
170#ifndef raw_cpu_read_1 177#ifndef raw_cpu_read_1
171#define raw_cpu_read_1(pcp) (*raw_cpu_ptr(&(pcp))) 178#define raw_cpu_read_1(pcp) raw_cpu_generic_read(pcp)
172#endif 179#endif
173#ifndef raw_cpu_read_2 180#ifndef raw_cpu_read_2
174#define raw_cpu_read_2(pcp) (*raw_cpu_ptr(&(pcp))) 181#define raw_cpu_read_2(pcp) raw_cpu_generic_read(pcp)
175#endif 182#endif
176#ifndef raw_cpu_read_4 183#ifndef raw_cpu_read_4
177#define raw_cpu_read_4(pcp) (*raw_cpu_ptr(&(pcp))) 184#define raw_cpu_read_4(pcp) raw_cpu_generic_read(pcp)
178#endif 185#endif
179#ifndef raw_cpu_read_8 186#ifndef raw_cpu_read_8
180#define raw_cpu_read_8(pcp) (*raw_cpu_ptr(&(pcp))) 187#define raw_cpu_read_8(pcp) raw_cpu_generic_read(pcp)
181#endif 188#endif
182 189
183#ifndef raw_cpu_write_1 190#ifndef raw_cpu_write_1