[PATCH v12 01/15] asm-generic: barrier: Add smp_cond_load_relaxed_timeout()
bot+bpf-ci at kernel.org
bot+bpf-ci at kernel.org
Mon Jun 8 01:53:25 PDT 2026
> diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h
> index d4f581c1e21d..c56df9513a08 100644
> --- a/include/asm-generic/barrier.h
> +++ b/include/asm-generic/barrier.h
> @@ -273,6 +273,75 @@ do { \
[ ... ]
> +#ifndef smp_cond_load_relaxed_timeout
> +#define smp_cond_load_relaxed_timeout(ptr, cond_expr, \
> + time_expr_ns, timeout_ns) \
> +({ \
> + typeof(ptr) __PTR = (ptr); \
> + __unqual_scalar_typeof(*(ptr)) VAL; \
> + u32 __count = 0, __spin = SMP_TIMEOUT_POLL_COUNT; \
> + s64 __timeout = (s64)timeout_ns; \
> + s64 __time_now, __time_end = 0; \
> + \
> + for (;;) { \
> + VAL = READ_ONCE(*__PTR); \
> + if (cond_expr) \
> + break; \
> + cpu_poll_relax(__PTR, VAL, (u64)__timeout); \
__timeout is held as a signed s64 but is cast to u64 here. On the first
iterations __timeout still holds the raw timeout_ns argument before any
time-check has run. If a caller passes a negative or already-expired
timeout_ns, the (u64) cast turns it into a value close to U64_MAX.
This is harmless while cpu_poll_relax() ignores its timeout argument and
falls back to cpu_relax(). Would it misbehave on an architecture whose
cpu_poll_relax() consumes the value, such as an arm64 WFET variant that
uses it as an event-stream deadline?
David Laight raised this on v11
(https://lore.kernel.org/lkml/20260508093206.389d9af2@pumpkin/):
Yes, the code is ok if cpu_poll_relax() ignores the timeout. But for
WFE it is all broken. ... if you assume/require that the converted
time is either 0 or greater than 200 then it can be used as the
initialiser for __n.
The Sashiko bot repeated the same concern as a medium finding on v12.
The v12 cover note opts to document the valid range rather than clamp at
runtime, but the code still passes (u64)__timeout unguarded, so would it
be worth converting timeout_ns into an absolute end-time (or 0 when WFE
is unused) before it reaches cpu_poll_relax()?
> + if (++__count < __spin) \
> + continue; \
> + __time_now = (s64)(time_expr_ns); \
> + if (unlikely(__time_end == 0)) \
> + __time_end = __time_now + __timeout; \
> + __timeout = __time_end - __time_now; \
> + if (__time_now <= 0 || __timeout <= 0) { \
> + VAL = READ_ONCE(*__PTR); \
> + break; \
> + } \
> + __count = 0; \
> + } \
> + (typeof(*(ptr)))VAL; \
> +})
> +#endif
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27125050324
More information about the linux-arm-kernel
mailing list