BPF List
 help / color / mirror / Atom feed
From: Ankur Arora <ankur.a.arora@oracle.com>
To: sashiko-reviews@lists.linux.dev, <linux-kernel@vger.kernel.org>,
	<linux-arch@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-pm@vger.kernel.org>, <bpf@vger.kernel.org>
Cc: <arnd@arndb.de>, <catalin.marinas@arm.com>, <will@kernel.org>,
	<peterz@infradead.org>, <akpm@linux-foundation.org>,
	<mark.rutland@arm.com>, <harisokn@amazon.com>, <cl@gentwo.org>,
	<ast@kernel.org>, <rafael@kernel.org>,
	<daniel.lezcano@linaro.org>, <memxor@gmail.com>,
	<zhenglifeng1@huawei.com>, <xueshuai@linux.alibaba.com>,
	<rdunlap@infradead.org>, <david.laight.linux@gmail.com>,
	<broonie@kernel.org>, <joao.m.martins@oracle.com>,
	<boris.ostrovsky@oracle.com>, <konrad.wilk@oracle.com>,
	<ashok.bhat@arm.com>, Ankur Arora <ankur.a.arora@oracle.com>
Subject: Re: [PATCH v14 01/15] asm-generic: barrier: Add smp_cond_load_relaxed_timeout()
Date: Thu, 30 Jul 2026 16:48:26 -0700	[thread overview]
Message-ID: <87bjbo2g51.fsf@oracle.com> (raw)
In-Reply-To: <20260714074238.3989E1F000E9@smtp.kernel.org>


sashiko-bot@kernel.org writes:

> Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
> - [High] Deferred time check causes massive timeout multiplication on architectures with precise waits.
> - [High] Unchecked negative initial timeout leads to an infinite hardware sleep.
> - [High] Generic local variable names in the macro cause dangerous variable shadowing.
> - [Medium] Missing parentheses around the `timeout_ns` macro argument.
> --
>
> --- Patch [1]: [PATCH v14 01/15] asm-generic: barrier: Add smp_cond_load_relaxed_timeout() ---
> commit fd56d26a441207368c7c3704e10f44093698b198
> Author: Ankur Arora <ankur.a.arora@oracle.com>
> Subject: asm-generic: barrier: Add smp_cond_load_relaxed_timeout()
>
> This patch introduces smp_cond_load_relaxed_timeout, extending the relaxed
> condition loader with a timeout mechanism. It implements a loop with
> cpu_poll_relax and defers time checks to a slowpath to minimize performance
> overhead.
>
>> diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h
>> index d4f581c1e21da..ecdaddbbd7b64 100644
>> --- a/include/asm-generic/barrier.h
>> +++ b/include/asm-generic/barrier.h
> [ ... ]
>> +#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;		\
>
> [Severity: High]
> Could these generic variable names cause variable shadowing issues?
>
> If a caller passes an expression for time_expr_ns or cond_expr that uses a
> variable named __count or __timeout, would it evaluate using the macro's
> internal variables instead of the caller's? For example, if the caller's
> timeout variable is named __timeout, might it initialize the macro's local
> variable with its own uninitialized value?

process/coding-style.rst does mention this case:

 5) namespace collisions when defining local variables in macros resembling
 functions:
   ...
  ret is a common name for a local variable - __foo_ret is less likely
  to collide with an existing variable.

This has an __ prefix, but I suppose a collision is possible. Will fix.

>> +	s64 __timeout = (s64)timeout_ns;				\
>
> [Severity: Medium]
> Is it possible for operator precedence to cause incorrect timeout calculations
> here?
>
> Since the timeout_ns macro argument is not enclosed in parentheses during the
> cast, if a caller passes an expression like a << b, the cast would apply only
> to the first operand instead of the entire expression.

Had missed this. Will fix.

>> +	s64 __time_now, __time_end = 0;					\
>> +									\
>> +	for (;;) {							\
>> +		VAL = READ_ONCE(*__PTR);				\
>> +		if (cond_expr)						\
>> +			break;						\
>> +		cpu_poll_relax(__PTR, VAL, (u64)__timeout);		\
>
> [Severity: High]
> What happens if the initial timeout_ns passed by the caller is zero or
> negative?
>
> Because the time validation is deferred for SMP_TIMEOUT_POLL_COUNT iterations,
> a negative initial timeout is cast to u64 on the very first loop iteration. On
> architectures that implement a precise hardware wait, could this extremely
> large unsigned value cause an infinite hardware sleep instead of returning
> immediately?

If an arch implements a precise hardware wait it doesn't make sense for it
to define SMP_TIMEOUT_POLL_COUNT to be anything but 1.

If the caller calls with timeout_ns=0, then in general it is architecture
defined if it results in an arbitray wait or immediate return.
(On arm64 it will result in an immediate return with WFET, and up to
100us delay with WFE.)

If the caller uses timeout_ns < 0, then this will result in a long sleep.

IMO something like this is best addressed at code review instead of adding
unnecessary checks in potentially fast path code.

However, in the typical case of constant value of timeout_ns, there's no
runtime cost to the check. So, I'll add a domain check at the top level.

That should remove a bunch of sashiko comments.

>> +		if (++__count < __spin)					\
>> +			continue;					\
>
> [Severity: High]
> Does this loop inadvertently multiply the wait time on architectures with
> precise waits?
>
> Since __timeout is repeatedly passed to cpu_poll_relax without being
> decremented inside the SMP_TIMEOUT_POLL_COUNT deferral loop, if the CPU wakes
> up spuriously, it appears it will sleep again for the full initial timeout
> duration up to 200 times. Could this cause significant latency spikes?

In theory, this could happen. However, as the comment above
cpu_poll_relax() says:

   /*
    * cpu_poll_relax() stitches up two kinds of primitives: ones that provide
    * a momentary blip in the pipeline (ex. cpu_relax() on x86).
    * The second support waiting for @ptr value to change, coupled with a
    * with a precise (or imprecise) timeout.
    *
    * cpu_poll_relax() keeps them together, because its utility is in minimizing
    * expensive operations while polling on @ptr waiting for it to change.
    * The arguments to cpu_poll_relax() are only needed for the waiting
    * primitives.
    * ... */

So, for cases where the arch implements a timeout it doesn't make sense
for it to define SMP_TIMEOUT_POLL_COUNT to be anything but 1.

That said, the deferral of the time-check (to ensure we don't pay a cost
in the fast path ex. the locking path in rqspinlock) will cause a delay
(potentially up to doubling the timeout.) That could be fixed with an
alternative like the one I posted in:
  https://lore.kernel.org/all/874iklm1uy.fsf@oracle.com/

However, after the discussion with David Laight I came to the view that
it just overcomplicates the implementation for no real gain.

A better fix is to just document that in the worst cae me might end up
waiting for double the timeout (this is documented in the commit message).

--
ankur

  reply	other threads:[~2026-07-30 23:49 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-14  7:30 [PATCH v14 00/15] barrier: Add smp_cond_load_{relaxed,acquire}_timeout() Ankur Arora
2026-07-14  7:30 ` [PATCH v14 01/15] asm-generic: barrier: Add smp_cond_load_relaxed_timeout() Ankur Arora
2026-07-14  7:42   ` sashiko-bot
2026-07-30 23:48     ` Ankur Arora [this message]
2026-07-14  8:11   ` bot+bpf-ci
2026-07-14  7:30 ` [PATCH v14 02/15] arm64: barrier: Support smp_cond_load_relaxed_timeout() Ankur Arora
2026-07-14  7:50   ` sashiko-bot
2026-07-30 23:09     ` Ankur Arora
2026-07-14  7:30 ` [PATCH v14 03/15] arm64/delay: move some constants out to a separate header Ankur Arora
2026-07-14  7:30 ` [PATCH v14 04/15] arm64: support WFET in smp_cond_load_relaxed_timeout() Ankur Arora
2026-07-14  7:53   ` sashiko-bot
2026-07-14  7:30 ` [PATCH v14 05/15] arm64: rqspinlock: Remove private copy of smp_cond_load_acquire_timewait() Ankur Arora
2026-07-14  7:44   ` sashiko-bot
2026-07-30 23:31     ` Ankur Arora
2026-07-14  7:30 ` [PATCH v14 06/15] asm-generic: barrier: Add smp_cond_load_acquire_timeout() Ankur Arora
2026-07-14  7:53   ` sashiko-bot
2026-07-14  7:30 ` [PATCH v14 07/15] atomic: Add atomic_cond_read_*_timeout() Ankur Arora
2026-07-14  7:47   ` sashiko-bot
2026-07-14  7:30 ` [PATCH v14 08/15] locking/atomic: scripts: build atomic_long_cond_read_*_timeout() Ankur Arora
2026-07-14  7:30 ` [PATCH v14 09/15] bpf/rqspinlock: switch check_timeout() to a clock interface Ankur Arora
2026-07-14  7:30 ` [PATCH v14 10/15] bpf/rqspinlock: Use smp_cond_load_acquire_timeout() Ankur Arora
2026-07-14  8:11   ` bot+bpf-ci
2026-07-14  7:30 ` [PATCH v14 11/15] sched: add need-resched timed wait interface Ankur Arora
2026-07-14  7:30 ` [PATCH v14 12/15] cpuidle/poll_state: Wait for need-resched via tif_need_resched_relaxed_wait() Ankur Arora
2026-07-14  8:11   ` bot+bpf-ci
2026-07-14  7:30 ` [PATCH v14 13/15] arm64/delay: enable testing smp_cond_load_relaxed_timeout() Ankur Arora
2026-07-14  7:58   ` sashiko-bot
2026-07-28 11:36   ` Will Deacon
2026-07-28 23:06     ` Ankur Arora
2026-07-14  7:30 ` [PATCH v14 14/15] barrier: add tests for smp_cond_load_*_timeout() Ankur Arora
2026-07-14  7:55   ` sashiko-bot
2026-07-14  8:11   ` bot+bpf-ci
2026-07-14  7:30 ` [PATCH v14 15/15] barrier: add clock tests for smp_cond_load_relaxed_timeout() Ankur Arora
2026-07-14  8:03   ` sashiko-bot
2026-07-16  7:01 ` [PATCH v14 00/15] barrier: Add smp_cond_load_{relaxed,acquire}_timeout() Ankur Arora
2026-07-28 23:34   ` Ankur Arora

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87bjbo2g51.fsf@oracle.com \
    --to=ankur.a.arora@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=arnd@arndb.de \
    --cc=ashok.bhat@arm.com \
    --cc=ast@kernel.org \
    --cc=boris.ostrovsky@oracle.com \
    --cc=bpf@vger.kernel.org \
    --cc=broonie@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=cl@gentwo.org \
    --cc=daniel.lezcano@linaro.org \
    --cc=david.laight.linux@gmail.com \
    --cc=harisokn@amazon.com \
    --cc=joao.m.martins@oracle.com \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=memxor@gmail.com \
    --cc=peterz@infradead.org \
    --cc=rafael@kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=will@kernel.org \
    --cc=xueshuai@linux.alibaba.com \
    --cc=zhenglifeng1@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox