@@ -305,6 +305,23 @@ static __always_inline void __write_once
})
/**
+ * cmpwait - compare and wait for a variable to change
+ * @ptr: pointer to the variable to wait on
+ * @val: the value it should change from
+ *
+ * A simple constuct that waits for a variable to change from a known
+ * value; some architectures can do this in hardware.
+ */
+#ifndef cmpwait
+#define cmpwait(ptr, val) do { \
+ typeof (ptr) __ptr = (ptr); \
+ typeof (val) __val = (val); \
+ while (READ_ONCE(*__ptr) == __val) \
+ cpu_relax(); \
+} while (0)
+#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
@@ -327,7 +344,7 @@ static __always_inline void __write_once
VAL = READ_ONCE(*__PTR); \
if (cond_expr) \
break; \
- cpu_relax(); \
+ cmpwait(__PTR, VAL); \
} \
smp_rmb(); /* ctrl + rmb := acquire */ \
VAL; \
Provide the cmpwait() primitive, which will 'spin' wait for a variable to change and use it to implement smp_cond_load_acquire(). This primitive can be implemented with hardware assist on some platforms (ARM64, x86). Suggested-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> --- include/linux/compiler.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html