diff options
author | Peter Zijlstra <peterz@infradead.org> | 2016-06-01 13:23:54 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-06-14 05:55:14 -0400 |
commit | 7cb45c0fe9858f92cc264f6bf9d2f6a0e7d3b249 (patch) | |
tree | f429581d6b993e303a297a461d06cd0dad58ea68 | |
parent | 33ac279677dcc2441cb93d8cb9cf7a74df62814d (diff) |
locking/barriers: Move smp_cond_load_acquire() to asm-generic/barrier.h
Since all asm/barrier.h should/must include asm-generic/barrier.h the
latter is a good place for generic infrastructure like this.
This also allows archs to override the new smp_acquire__after_ctrl_dep().
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | include/asm-generic/barrier.h | 39 | ||||
-rw-r--r-- | include/linux/compiler.h | 37 |
2 files changed, 39 insertions, 37 deletions
diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h index 1cceca146905..ab7b0bd7d4dd 100644 --- a/include/asm-generic/barrier.h +++ b/include/asm-generic/barrier.h | |||
@@ -207,5 +207,44 @@ do { \ | |||
207 | #define virt_store_release(p, v) __smp_store_release(p, v) | 207 | #define virt_store_release(p, v) __smp_store_release(p, v) |
208 | #define virt_load_acquire(p) __smp_load_acquire(p) | 208 | #define virt_load_acquire(p) __smp_load_acquire(p) |
209 | 209 | ||
210 | /** | ||
211 | * smp_acquire__after_ctrl_dep() - Provide ACQUIRE ordering after a control dependency | ||
212 | * | ||
213 | * A control dependency provides a LOAD->STORE order, the additional RMB | ||
214 | * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} order, | ||
215 | * aka. (load)-ACQUIRE. | ||
216 | * | ||
217 | * Architectures that do not do load speculation can have this be barrier(). | ||
218 | */ | ||
219 | #ifndef smp_acquire__after_ctrl_dep | ||
220 | #define smp_acquire__after_ctrl_dep() smp_rmb() | ||
221 | #endif | ||
222 | |||
223 | /** | ||
224 | * smp_cond_load_acquire() - (Spin) wait for cond with ACQUIRE ordering | ||
225 | * @ptr: pointer to the variable to wait on | ||
226 | * @cond: boolean expression to wait for | ||
227 | * | ||
228 | * Equivalent to using smp_load_acquire() on the condition variable but employs | ||
229 | * the control dependency of the wait to reduce the barrier on many platforms. | ||
230 | * | ||
231 | * Due to C lacking lambda expressions we load the value of *ptr into a | ||
232 | * pre-named variable @VAL to be used in @cond. | ||
233 | */ | ||
234 | #ifndef smp_cond_load_acquire | ||
235 | #define smp_cond_load_acquire(ptr, cond_expr) ({ \ | ||
236 | typeof(ptr) __PTR = (ptr); \ | ||
237 | typeof(*ptr) VAL; \ | ||
238 | for (;;) { \ | ||
239 | VAL = READ_ONCE(*__PTR); \ | ||
240 | if (cond_expr) \ | ||
241 | break; \ | ||
242 | cpu_relax(); \ | ||
243 | } \ | ||
244 | smp_acquire__after_ctrl_dep(); \ | ||
245 | VAL; \ | ||
246 | }) | ||
247 | #endif | ||
248 | |||
210 | #endif /* !__ASSEMBLY__ */ | 249 | #endif /* !__ASSEMBLY__ */ |
211 | #endif /* __ASM_GENERIC_BARRIER_H */ | 250 | #endif /* __ASM_GENERIC_BARRIER_H */ |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 59a7004fc7dd..2e853b679a5d 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -304,43 +304,6 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s | |||
304 | __u.__val; \ | 304 | __u.__val; \ |
305 | }) | 305 | }) |
306 | 306 | ||
307 | /** | ||
308 | * smp_acquire__after_ctrl_dep() - Provide ACQUIRE ordering after a control dependency | ||
309 | * | ||
310 | * A control dependency provides a LOAD->STORE order, the additional RMB | ||
311 | * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} order, | ||
312 | * aka. (load)-ACQUIRE. | ||
313 | * | ||
314 | * Architectures that do not do load speculation can have this be barrier(). | ||
315 | */ | ||
316 | #define smp_acquire__after_ctrl_dep() smp_rmb() | ||
317 | |||
318 | /** | ||
319 | * smp_cond_load_acquire() - (Spin) wait for cond with ACQUIRE ordering | ||
320 | * @ptr: pointer to the variable to wait on | ||
321 | * @cond: boolean expression to wait for | ||
322 | * | ||
323 | * Equivalent to using smp_load_acquire() on the condition variable but employs | ||
324 | * the control dependency of the wait to reduce the barrier on many platforms. | ||
325 | * | ||
326 | * Due to C lacking lambda expressions we load the value of *ptr into a | ||
327 | * pre-named variable @VAL to be used in @cond. | ||
328 | */ | ||
329 | #ifndef smp_cond_load_acquire | ||
330 | #define smp_cond_load_acquire(ptr, cond_expr) ({ \ | ||
331 | typeof(ptr) __PTR = (ptr); \ | ||
332 | typeof(*ptr) VAL; \ | ||
333 | for (;;) { \ | ||
334 | VAL = READ_ONCE(*__PTR); \ | ||
335 | if (cond_expr) \ | ||
336 | break; \ | ||
337 | cpu_relax(); \ | ||
338 | } \ | ||
339 | smp_acquire__after_ctrl_dep(); \ | ||
340 | VAL; \ | ||
341 | }) | ||
342 | #endif | ||
343 | |||
344 | #endif /* __KERNEL__ */ | 307 | #endif /* __KERNEL__ */ |
345 | 308 | ||
346 | #endif /* __ASSEMBLY__ */ | 309 | #endif /* __ASSEMBLY__ */ |