diff options
| author | Peter Zijlstra <peterz@infradead.org> | 2016-05-24 07:17:12 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2016-06-14 05:55:14 -0400 |
| commit | 33ac279677dcc2441cb93d8cb9cf7a74df62814d (patch) | |
| tree | bcf918587b2425d1294b780b31ab67761e068e26 /include/linux/compiler.h | |
| parent | 1f03e8d2919270bd6ef64f39a45ce8df8a9f012a (diff) | |
locking/barriers: Introduce smp_acquire__after_ctrl_dep()
Introduce smp_acquire__after_ctrl_dep(), this construct is not
uncommon, but the lack of this barrier is.
Use it to better express smp_rmb() uses in WRITE_ONCE(), the IPC
semaphore code and the qspinlock code.
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>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include/linux/compiler.h')
| -rw-r--r-- | include/linux/compiler.h | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 2bcaedc0f032..59a7004fc7dd 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
| @@ -305,6 +305,17 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s | |||
| 305 | }) | 305 | }) |
| 306 | 306 | ||
| 307 | /** | 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 | /** | ||
| 308 | * smp_cond_load_acquire() - (Spin) wait for cond with ACQUIRE ordering | 319 | * smp_cond_load_acquire() - (Spin) wait for cond with ACQUIRE ordering |
| 309 | * @ptr: pointer to the variable to wait on | 320 | * @ptr: pointer to the variable to wait on |
| 310 | * @cond: boolean expression to wait for | 321 | * @cond: boolean expression to wait for |
| @@ -314,10 +325,6 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s | |||
| 314 | * | 325 | * |
| 315 | * Due to C lacking lambda expressions we load the value of *ptr into a | 326 | * Due to C lacking lambda expressions we load the value of *ptr into a |
| 316 | * pre-named variable @VAL to be used in @cond. | 327 | * pre-named variable @VAL to be used in @cond. |
| 317 | * | ||
| 318 | * The control dependency provides a LOAD->STORE order, the additional RMB | ||
| 319 | * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} order, | ||
| 320 | * aka. ACQUIRE. | ||
| 321 | */ | 328 | */ |
| 322 | #ifndef smp_cond_load_acquire | 329 | #ifndef smp_cond_load_acquire |
| 323 | #define smp_cond_load_acquire(ptr, cond_expr) ({ \ | 330 | #define smp_cond_load_acquire(ptr, cond_expr) ({ \ |
| @@ -329,7 +336,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s | |||
| 329 | break; \ | 336 | break; \ |
| 330 | cpu_relax(); \ | 337 | cpu_relax(); \ |
| 331 | } \ | 338 | } \ |
| 332 | smp_rmb(); /* ctrl + rmb := acquire */ \ | 339 | smp_acquire__after_ctrl_dep(); \ |
| 333 | VAL; \ | 340 | VAL; \ |
| 334 | }) | 341 | }) |
| 335 | #endif | 342 | #endif |
