Skip to content

Commit 13ab6be

Browse files
terminusKernel Patches Daemon
authored andcommitted
asm-generic: barrier: Add smp_cond_load_relaxed_timeout()
Add smp_cond_load_relaxed_timeout(), which extends smp_cond_load_relaxed() to allow waiting for a duration. The waiting loop uses cpu_poll_relax() to wait on the condition variable with a periodic evaluation of a time-check. cpu_poll_relax() unless overridden by the arch code, amounts to a cpu_relax(). The number of times we spin is defined by SMP_TIMEOUT_POLL_COUNT (chosen to be 200 by default) which, assuming each cpu_poll_relax() iteration takes around 20-30 cycles (measured on a variety of x86 platforms), for a total of ~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] Reviewed-by: Catalin Marinas <[email protected]> Reviewed-by: Haris Okanovic <[email protected]> Tested-by: Haris Okanovic <[email protected]> Signed-off-by: Ankur Arora <[email protected]>
1 parent 583dec7 commit 13ab6be

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

include/asm-generic/barrier.h

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

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

0 commit comments

Comments
 (0)