[B:linux][B:linux-aws][PATCH 1/2] locking/barriers: Introduce smp_cond_load_relaxed() and atomic_cond_read_relaxed()
Stefan Bader
stefan.bader at canonical.com
Tue Apr 27 12:27:26 UTC 2021
On 26.04.21 23:41, Guilherme G. Piccoli wrote:
> From: Will Deacon <will.deacon at arm.com>
>
> BugLink: https://bugs.launchpad.net/bugs/1926184
>
> Whilst we currently provide smp_cond_load_acquire() and
> atomic_cond_read_acquire(), there are cases where the ACQUIRE semantics are
> not required because of a subsequent fence or release operation once the
> conditional loop has exited.
>
> This patch adds relaxed versions of the conditional spinning primitives
> to avoid unnecessary barrier overhead on architectures such as arm64.
>
> Signed-off-by: Will Deacon <will.deacon at arm.com>
> Acked-by: Peter Zijlstra (Intel) <peterz at infradead.org>
> Acked-by: Waiman Long <longman at redhat.com>
> Cc: Linus Torvalds <torvalds at linux-foundation.org>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: boqun.feng at gmail.com
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: paulmck at linux.vnet.ibm.com
> Link: http://lkml.kernel.org/r/1524738868-31318-2-git-send-email-will.deacon@arm.com
> Signed-off-by: Ingo Molnar <mingo at kernel.org>
> (cherry picked from commit fcfdfe30e324725007e9dc5814b62a4c430ea909)
> Signed-off-by: Guilherme G. Piccoli <gpiccoli at canonical.com>
> ---
Target is bionic:linux AND bionic:linux-aws. But bionic:linux-aws is a
derivative of bionic:linux. Why mention aws individually?
-Stefan
> include/asm-generic/atomic-long.h | 2 ++
> include/asm-generic/barrier.h | 27 +++++++++++++++++++++------
> include/linux/atomic.h | 2 ++
> 3 files changed, 25 insertions(+), 6 deletions(-)
>
> diff --git a/include/asm-generic/atomic-long.h b/include/asm-generic/atomic-long.h
> index 34a028a7bcc5..5b2b0b5ea06d 100644
> --- a/include/asm-generic/atomic-long.h
> +++ b/include/asm-generic/atomic-long.h
> @@ -244,6 +244,8 @@ static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
> #define atomic_long_inc_not_zero(l) \
> ATOMIC_LONG_PFX(_inc_not_zero)((ATOMIC_LONG_PFX(_t) *)(l))
>
> +#define atomic_long_cond_read_relaxed(v, c) \
> + ATOMIC_LONG_PFX(_cond_read_relaxed)((ATOMIC_LONG_PFX(_t) *)(v), (c))
> #define atomic_long_cond_read_acquire(v, c) \
> ATOMIC_LONG_PFX(_cond_read_acquire)((ATOMIC_LONG_PFX(_t) *)(v), (c))
>
> diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h
> index fe297b599b0a..305e03b19a26 100644
> --- a/include/asm-generic/barrier.h
> +++ b/include/asm-generic/barrier.h
> @@ -221,18 +221,17 @@ do { \
> #endif
>
> /**
> - * smp_cond_load_acquire() - (Spin) wait for cond with ACQUIRE ordering
> + * smp_cond_load_relaxed() - (Spin) wait for cond with no ordering guarantees
> * @ptr: pointer to the variable to wait on
> * @cond: boolean expression to wait for
> *
> - * Equivalent to using smp_load_acquire() on the condition variable but employs
> - * the control dependency of the wait to reduce the barrier on many platforms.
> + * Equivalent to using READ_ONCE() on the condition variable.
> *
> * Due to C lacking lambda expressions we load the value of *ptr into a
> * pre-named variable @VAL to be used in @cond.
> */
> -#ifndef smp_cond_load_acquire
> -#define smp_cond_load_acquire(ptr, cond_expr) ({ \
> +#ifndef smp_cond_load_relaxed
> +#define smp_cond_load_relaxed(ptr, cond_expr) ({ \
> typeof(ptr) __PTR = (ptr); \
> typeof(*ptr) VAL; \
> for (;;) { \
> @@ -241,10 +240,26 @@ do { \
> break; \
> cpu_relax(); \
> } \
> - smp_acquire__after_ctrl_dep(); \
> VAL; \
> })
> #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
> + *
> + * Equivalent to using smp_load_acquire() on the condition variable but employs
> + * the control dependency of the wait to reduce the barrier on many platforms.
> + */
> +#ifndef smp_cond_load_acquire
> +#define smp_cond_load_acquire(ptr, cond_expr) ({ \
> + typeof(*ptr) _val; \
> + _val = smp_cond_load_relaxed(ptr, cond_expr); \
> + smp_acquire__after_ctrl_dep(); \
> + _val; \
> +})
> +#endif
> +
> #endif /* !__ASSEMBLY__ */
> #endif /* __ASM_GENERIC_BARRIER_H */
> diff --git a/include/linux/atomic.h b/include/linux/atomic.h
> index 8b276fd9a127..01ce3997cb42 100644
> --- a/include/linux/atomic.h
> +++ b/include/linux/atomic.h
> @@ -654,6 +654,7 @@ static inline int atomic_dec_if_positive(atomic_t *v)
> }
> #endif
>
> +#define atomic_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
> #define atomic_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c))
>
> #ifdef CONFIG_GENERIC_ATOMIC64
> @@ -1075,6 +1076,7 @@ static inline long long atomic64_fetch_andnot_release(long long i, atomic64_t *v
> }
> #endif
>
> +#define atomic64_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
> #define atomic64_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c))
>
> #include <asm-generic/atomic-long.h>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20210427/a13ab835/attachment.sig>
More information about the kernel-team
mailing list