diff options
Diffstat (limited to 'include/asm-generic/barrier.h')
| -rw-r--r-- | include/asm-generic/barrier.h | 41 | 
1 files changed, 40 insertions, 1 deletions
| diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h index 1cceca146905..fe297b599b0a 100644 --- a/include/asm-generic/barrier.h +++ b/include/asm-generic/barrier.h @@ -194,7 +194,7 @@ do {									\  })  #endif -#endif +#endif	/* CONFIG_SMP */  /* Barriers for virtual machine guests when talking to an SMP host */  #define virt_mb() __smp_mb() @@ -207,5 +207,44 @@ do {									\  #define virt_store_release(p, v) __smp_store_release(p, v)  #define virt_load_acquire(p) __smp_load_acquire(p) +/** + * smp_acquire__after_ctrl_dep() - Provide ACQUIRE ordering after a control dependency + * + * A control dependency provides a LOAD->STORE order, the additional RMB + * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} order, + * aka. (load)-ACQUIRE. + * + * Architectures that do not do load speculation can have this be barrier(). + */ +#ifndef smp_acquire__after_ctrl_dep +#define smp_acquire__after_ctrl_dep()		smp_rmb() +#endif + +/** + * smp_cond_load_acquire() - (Spin) wait for cond with ACQUIRE ordering + * @ptr: pointer to the variable to wait on + * @cond: boolean expression to wait for + * + * Equivalent to using smp_load_acquire() on the condition variable but employs + * the control dependency of the wait to reduce the barrier on many platforms. + * + * Due to C lacking lambda expressions we load the value of *ptr into a + * pre-named variable @VAL to be used in @cond. + */ +#ifndef smp_cond_load_acquire +#define smp_cond_load_acquire(ptr, cond_expr) ({		\ +	typeof(ptr) __PTR = (ptr);				\ +	typeof(*ptr) VAL;					\ +	for (;;) {						\ +		VAL = READ_ONCE(*__PTR);			\ +		if (cond_expr)					\ +			break;					\ +		cpu_relax();					\ +	}							\ +	smp_acquire__after_ctrl_dep();				\ +	VAL;							\ +}) +#endif +  #endif /* !__ASSEMBLY__ */  #endif /* __ASM_GENERIC_BARRIER_H */ |