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 /include/asm-generic | |
| 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>
Diffstat (limited to 'include/asm-generic')
| -rw-r--r-- | include/asm-generic/barrier.h | 39 |
1 files changed, 39 insertions, 0 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 */ |
