Skip to content

Commit 71c3851

Browse files
terminusKernel Patches Daemon
authored andcommitted
asm-generic: barrier: Add smp_cond_load_relaxed_timewait()
Add smp_cond_load_relaxed_timewait(), which extends smp_cond_load_relaxed() to allow waiting for a finite duration. The additional parameter allows for the timeout check. The waiting is done via the usual cpu_relax() spin-wait around the condition variable with periodic evaluation of the time-check. The number of times we spin is defined by SMP_TIMEWAIT_SPIN_COUNT (chosen to be 200 by default) which, assuming each cpu_relax() iteration takes around 20-30 cycles (measured on a variety of x86 platforms), amounts to around 4000-6000 cycles. Cc: Arnd Bergmann <[email protected]> Cc: Will Deacon <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: [email protected] Signed-off-by: Ankur Arora <[email protected]> Reviewed-by: Catalin Marinas <[email protected]>
1 parent 4754b79 commit 71c3851

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

include/asm-generic/barrier.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,41 @@ do { \
273273
})
274274
#endif
275275

276+
#ifndef SMP_TIMEWAIT_SPIN_COUNT
277+
#define SMP_TIMEWAIT_SPIN_COUNT 200
278+
#endif
279+
280+
/**
281+
* smp_cond_load_relaxed_timewait() - (Spin) wait for cond with no ordering
282+
* guarantees until a timeout expires.
283+
* @ptr: pointer to the variable to wait on
284+
* @cond: boolean expression to wait for
285+
* @time_check_expr: expression to decide when to bail out
286+
*
287+
* Equivalent to using READ_ONCE() on the condition variable.
288+
*/
289+
#ifndef smp_cond_load_relaxed_timewait
290+
#define smp_cond_load_relaxed_timewait(ptr, cond_expr, time_check_expr) \
291+
({ \
292+
typeof(ptr) __PTR = (ptr); \
293+
__unqual_scalar_typeof(*ptr) VAL; \
294+
u32 __n = 0, __spin = SMP_TIMEWAIT_SPIN_COUNT; \
295+
\
296+
for (;;) { \
297+
VAL = READ_ONCE(*__PTR); \
298+
if (cond_expr) \
299+
break; \
300+
cpu_relax(); \
301+
if (++__n < __spin) \
302+
continue; \
303+
if (time_check_expr) \
304+
break; \
305+
__n = 0; \
306+
} \
307+
(typeof(*ptr))VAL; \
308+
})
309+
#endif
310+
276311
/*
277312
* pmem_wmb() ensures that all stores for which the modification
278313
* are written to persistent storage by preceding instructions have

0 commit comments

Comments
 (0)