[locking/atomic,18/19] locking/atomic: Refrain from generating duplicate fallback kernel-doc

Message ID 20230510181717.2200934-18-paulmck@kernel.org
State New
Headers
Series Add kernel-doc for more atomic operations |

Commit Message

Paul E. McKenney May 10, 2023, 6:17 p.m. UTC
  The gen-atomics.sh script currently generates 42 duplicate definitions:

	arch_atomic64_add_negative
	arch_atomic64_add_negative_acquire
	arch_atomic64_add_negative_release
	arch_atomic64_dec_return
	arch_atomic64_dec_return_acquire
	arch_atomic64_dec_return_release
	arch_atomic64_fetch_andnot
	arch_atomic64_fetch_andnot_acquire
	arch_atomic64_fetch_andnot_release
	arch_atomic64_fetch_dec
	arch_atomic64_fetch_dec_acquire
	arch_atomic64_fetch_dec_release
	arch_atomic64_fetch_inc
	arch_atomic64_fetch_inc_acquire
	arch_atomic64_fetch_inc_release
	arch_atomic64_inc_return
	arch_atomic64_inc_return_acquire
	arch_atomic64_inc_return_release
	arch_atomic64_try_cmpxchg
	arch_atomic64_try_cmpxchg_acquire
	arch_atomic64_try_cmpxchg_release
	arch_atomic_add_negative
	arch_atomic_add_negative_acquire
	arch_atomic_add_negative_release
	arch_atomic_dec_return
	arch_atomic_dec_return_acquire
	arch_atomic_dec_return_release
	arch_atomic_fetch_andnot
	arch_atomic_fetch_andnot_acquire
	arch_atomic_fetch_andnot_release
	arch_atomic_fetch_dec
	arch_atomic_fetch_dec_acquire
	arch_atomic_fetch_dec_release
	arch_atomic_fetch_inc
	arch_atomic_fetch_inc_acquire
	arch_atomic_fetch_inc_release
	arch_atomic_inc_return
	arch_atomic_inc_return_acquire
	arch_atomic_inc_return_release
	arch_atomic_try_cmpxchg
	arch_atomic_try_cmpxchg_acquire
	arch_atomic_try_cmpxchg_release

These duplicates are presumably to handle different architectures
generating hand-coded definitions for different subsets of the atomic
operations.  However, generating duplicate kernel-doc headers is
undesirable.

Therefore, generate only the first kernel-doc definition in a group
of duplicates.  A comment indicates the name of the function and the
fallback script that generated it.

Reported-by: Akira Yokosawa <akiyks@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Mark Rutland <mark.rutland@arm.com>
---
 include/linux/atomic/atomic-arch-fallback.h  | 386 +++----------------
 scripts/atomic/chkdup.sh                     |  27 ++
 scripts/atomic/fallbacks/acquire             |   3 +
 scripts/atomic/fallbacks/add_negative        |   5 +
 scripts/atomic/fallbacks/add_unless          |   5 +
 scripts/atomic/fallbacks/andnot              |   5 +
 scripts/atomic/fallbacks/dec                 |   5 +
 scripts/atomic/fallbacks/dec_and_test        |   5 +
 scripts/atomic/fallbacks/dec_if_positive     |   5 +
 scripts/atomic/fallbacks/dec_unless_positive |   5 +
 scripts/atomic/fallbacks/fence               |   3 +
 scripts/atomic/fallbacks/fetch_add_unless    |   5 +
 scripts/atomic/fallbacks/inc                 |   5 +
 scripts/atomic/fallbacks/inc_and_test        |   5 +
 scripts/atomic/fallbacks/inc_not_zero        |   5 +
 scripts/atomic/fallbacks/inc_unless_negative |   5 +
 scripts/atomic/fallbacks/read_acquire        |   5 +
 scripts/atomic/fallbacks/release             |   3 +
 scripts/atomic/fallbacks/set_release         |   5 +
 scripts/atomic/fallbacks/sub_and_test        |   5 +
 scripts/atomic/fallbacks/try_cmpxchg         |   5 +
 scripts/atomic/gen-atomics.sh                |   4 +
 22 files changed, 163 insertions(+), 343 deletions(-)
 create mode 100644 scripts/atomic/chkdup.sh
  

Comments

Mark Rutland May 11, 2023, 5:10 p.m. UTC | #1
Hi Paul

On Wed, May 10, 2023 at 11:17:16AM -0700, Paul E. McKenney wrote:
> The gen-atomics.sh script currently generates 42 duplicate definitions:
> 
> 	arch_atomic64_add_negative
> 	arch_atomic64_add_negative_acquire
> 	arch_atomic64_add_negative_release

	[...]

> These duplicates are presumably to handle different architectures
> generating hand-coded definitions for different subsets of the atomic
> operations.

Yup, for each FULL/ACQUIRE/RELEASE/RELAXED variant of each op, we allow the
archtiecture to choose between:

* Providing the ordering variant directly
* Providing the FULL ordering variant only
* Providing the RELAXED ordering variant only
* Providing an equivalent op that we can build from

> However, generating duplicate kernel-doc headers is undesirable.

Understood -- I hadn't understood that duplication was a problem when this was
originally written.

The way this is currently done is largely an artifact of our ifdeffery (and the
kerneldoc for fallbacks living inthe fallback templates), and I think we can
fix both of those.

> Therefore, generate only the first kernel-doc definition in a group
> of duplicates.  A comment indicates the name of the function and the
> fallback script that generated it.

I'm not keen on this approach, especially with the chkdup.sh script -- it feels
like we're working around an underlying structural issue.

I think that we can restructure the ifdeffery so that each ordering variant
gets its own ifdeffery, and then we could place the kerneldoc immediately above
that, e.g.

	/**
	 * arch_atomic_inc_return_release()
	 *
	 * [ full kerneldoc block here ]
	 */
	#if defined(arch_atomic_inc_return_release)
	/* defined in arch code */
	#elif defined(arch_atomic_inc_return_relaxed)
	[ define in terms of arch_atomic_inc_return_relaxed ]
	#elif defined(arch_atomic_inc_return)
	[ define in terms of arch_atomic_inc_return ]
	#else
	[ define in terms of arch_atomic_fetch_inc_release ]
	#endif

... with similar for the mandatory ops that each arch must provide, e.g.

	/**
	 * arch_atomic_or()
	 *
	 * [ full kerneldoc block here ]
	 */
	/* arch_atomic_or() is mandatory -- architectures must define it! */

I had a go at that restructuring today, and while local build testing indicates
I haven't got it quite right, I think it's possible:

  https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework

Does that sound ok to you?

Thanks,
Mark.

> Reported-by: Akira Yokosawa <akiyks@gmail.com>
> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> Cc: Will Deacon <will@kernel.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Boqun Feng <boqun.feng@gmail.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> ---
>  include/linux/atomic/atomic-arch-fallback.h  | 386 +++----------------
>  scripts/atomic/chkdup.sh                     |  27 ++
>  scripts/atomic/fallbacks/acquire             |   3 +
>  scripts/atomic/fallbacks/add_negative        |   5 +
>  scripts/atomic/fallbacks/add_unless          |   5 +
>  scripts/atomic/fallbacks/andnot              |   5 +
>  scripts/atomic/fallbacks/dec                 |   5 +
>  scripts/atomic/fallbacks/dec_and_test        |   5 +
>  scripts/atomic/fallbacks/dec_if_positive     |   5 +
>  scripts/atomic/fallbacks/dec_unless_positive |   5 +
>  scripts/atomic/fallbacks/fence               |   3 +
>  scripts/atomic/fallbacks/fetch_add_unless    |   5 +
>  scripts/atomic/fallbacks/inc                 |   5 +
>  scripts/atomic/fallbacks/inc_and_test        |   5 +
>  scripts/atomic/fallbacks/inc_not_zero        |   5 +
>  scripts/atomic/fallbacks/inc_unless_negative |   5 +
>  scripts/atomic/fallbacks/read_acquire        |   5 +
>  scripts/atomic/fallbacks/release             |   3 +
>  scripts/atomic/fallbacks/set_release         |   5 +
>  scripts/atomic/fallbacks/sub_and_test        |   5 +
>  scripts/atomic/fallbacks/try_cmpxchg         |   5 +
>  scripts/atomic/gen-atomics.sh                |   4 +
>  22 files changed, 163 insertions(+), 343 deletions(-)
>  create mode 100644 scripts/atomic/chkdup.sh
> 
> diff --git a/include/linux/atomic/atomic-arch-fallback.h b/include/linux/atomic/atomic-arch-fallback.h
> index 41aa94f0aacd..2d56726f8662 100644
> --- a/include/linux/atomic/atomic-arch-fallback.h
> +++ b/include/linux/atomic/atomic-arch-fallback.h
> @@ -639,13 +639,7 @@ arch_atomic_inc_return_relaxed(atomic_t *v)
>  #else /* arch_atomic_inc_return_relaxed */
>  
>  #ifndef arch_atomic_inc_return_acquire
> -/**
> - * arch_atomic_inc_return_acquire - Atomic inc with acquire ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically increment @v using acquire ordering.
> - * Return new value.
> - */
> +// Fallback acquire omitting duplicate arch_atomic_inc_return_acquire() kernel-doc header.
>  static __always_inline int
>  arch_atomic_inc_return_acquire(atomic_t *v)
>  {
> @@ -657,13 +651,7 @@ arch_atomic_inc_return_acquire(atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_inc_return_release
> -/**
> - * arch_atomic_inc_return_release - Atomic inc with release ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically increment @v using release ordering.
> - * Return new value.
> - */
> +// Fallback release omitting duplicate arch_atomic_inc_return_release() kernel-doc header.
>  static __always_inline int
>  arch_atomic_inc_return_release(atomic_t *v)
>  {
> @@ -674,13 +662,7 @@ arch_atomic_inc_return_release(atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_inc_return
> -/**
> - * arch_atomic_inc_return - Atomic inc with full ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically increment @v using full ordering.
> - * Return new value.
> - */
> +// Fallback fence omitting duplicate arch_atomic_inc_return() kernel-doc header.
>  static __always_inline int
>  arch_atomic_inc_return(atomic_t *v)
>  {
> @@ -769,13 +751,7 @@ arch_atomic_fetch_inc_relaxed(atomic_t *v)
>  #else /* arch_atomic_fetch_inc_relaxed */
>  
>  #ifndef arch_atomic_fetch_inc_acquire
> -/**
> - * arch_atomic_fetch_inc_acquire - Atomic inc with acquire ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically increment @v using acquire ordering.
> - * Return old value.
> - */
> +// Fallback acquire omitting duplicate arch_atomic_fetch_inc_acquire() kernel-doc header.
>  static __always_inline int
>  arch_atomic_fetch_inc_acquire(atomic_t *v)
>  {
> @@ -787,13 +763,7 @@ arch_atomic_fetch_inc_acquire(atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_fetch_inc_release
> -/**
> - * arch_atomic_fetch_inc_release - Atomic inc with release ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically increment @v using release ordering.
> - * Return old value.
> - */
> +// Fallback release omitting duplicate arch_atomic_fetch_inc_release() kernel-doc header.
>  static __always_inline int
>  arch_atomic_fetch_inc_release(atomic_t *v)
>  {
> @@ -804,13 +774,7 @@ arch_atomic_fetch_inc_release(atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_fetch_inc
> -/**
> - * arch_atomic_fetch_inc - Atomic inc with full ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically increment @v using full ordering.
> - * Return old value.
> - */
> +// Fallback fence omitting duplicate arch_atomic_fetch_inc() kernel-doc header.
>  static __always_inline int
>  arch_atomic_fetch_inc(atomic_t *v)
>  {
> @@ -915,13 +879,7 @@ arch_atomic_dec_return_relaxed(atomic_t *v)
>  #else /* arch_atomic_dec_return_relaxed */
>  
>  #ifndef arch_atomic_dec_return_acquire
> -/**
> - * arch_atomic_dec_return_acquire - Atomic dec with acquire ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically decrement @v using acquire ordering.
> - * Return new value.
> - */
> +// Fallback acquire omitting duplicate arch_atomic_dec_return_acquire() kernel-doc header.
>  static __always_inline int
>  arch_atomic_dec_return_acquire(atomic_t *v)
>  {
> @@ -933,13 +891,7 @@ arch_atomic_dec_return_acquire(atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_dec_return_release
> -/**
> - * arch_atomic_dec_return_release - Atomic dec with release ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically decrement @v using release ordering.
> - * Return new value.
> - */
> +// Fallback release omitting duplicate arch_atomic_dec_return_release() kernel-doc header.
>  static __always_inline int
>  arch_atomic_dec_return_release(atomic_t *v)
>  {
> @@ -950,13 +902,7 @@ arch_atomic_dec_return_release(atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_dec_return
> -/**
> - * arch_atomic_dec_return - Atomic dec with full ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically decrement @v using full ordering.
> - * Return new value.
> - */
> +// Fallback fence omitting duplicate arch_atomic_dec_return() kernel-doc header.
>  static __always_inline int
>  arch_atomic_dec_return(atomic_t *v)
>  {
> @@ -1045,13 +991,7 @@ arch_atomic_fetch_dec_relaxed(atomic_t *v)
>  #else /* arch_atomic_fetch_dec_relaxed */
>  
>  #ifndef arch_atomic_fetch_dec_acquire
> -/**
> - * arch_atomic_fetch_dec_acquire - Atomic dec with acquire ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically decrement @v using acquire ordering.
> - * Return old value.
> - */
> +// Fallback acquire omitting duplicate arch_atomic_fetch_dec_acquire() kernel-doc header.
>  static __always_inline int
>  arch_atomic_fetch_dec_acquire(atomic_t *v)
>  {
> @@ -1063,13 +1003,7 @@ arch_atomic_fetch_dec_acquire(atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_fetch_dec_release
> -/**
> - * arch_atomic_fetch_dec_release - Atomic dec with release ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically decrement @v using release ordering.
> - * Return old value.
> - */
> +// Fallback release omitting duplicate arch_atomic_fetch_dec_release() kernel-doc header.
>  static __always_inline int
>  arch_atomic_fetch_dec_release(atomic_t *v)
>  {
> @@ -1080,13 +1014,7 @@ arch_atomic_fetch_dec_release(atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_fetch_dec
> -/**
> - * arch_atomic_fetch_dec - Atomic dec with full ordering
> - * @v: pointer of type atomic_t
> - *
> - * Atomically decrement @v using full ordering.
> - * Return old value.
> - */
> +// Fallback fence omitting duplicate arch_atomic_fetch_dec() kernel-doc header.
>  static __always_inline int
>  arch_atomic_fetch_dec(atomic_t *v)
>  {
> @@ -1262,14 +1190,7 @@ arch_atomic_fetch_andnot_relaxed(int i, atomic_t *v)
>  #else /* arch_atomic_fetch_andnot_relaxed */
>  
>  #ifndef arch_atomic_fetch_andnot_acquire
> -/**
> - * arch_atomic_fetch_andnot_acquire - Atomic andnot with acquire ordering
> - * @i: value to complement then AND
> - * @v: pointer of type atomic_t
> - *
> - * Atomically complement then AND @i with @v using acquire ordering.
> - * Return old value.
> - */
> +// Fallback acquire omitting duplicate arch_atomic_fetch_andnot_acquire() kernel-doc header.
>  static __always_inline int
>  arch_atomic_fetch_andnot_acquire(int i, atomic_t *v)
>  {
> @@ -1281,14 +1202,7 @@ arch_atomic_fetch_andnot_acquire(int i, atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_fetch_andnot_release
> -/**
> - * arch_atomic_fetch_andnot_release - Atomic andnot with release ordering
> - * @i: value to complement then AND
> - * @v: pointer of type atomic_t
> - *
> - * Atomically complement then AND @i with @v using release ordering.
> - * Return old value.
> - */
> +// Fallback release omitting duplicate arch_atomic_fetch_andnot_release() kernel-doc header.
>  static __always_inline int
>  arch_atomic_fetch_andnot_release(int i, atomic_t *v)
>  {
> @@ -1299,14 +1213,7 @@ arch_atomic_fetch_andnot_release(int i, atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_fetch_andnot
> -/**
> - * arch_atomic_fetch_andnot - Atomic andnot with full ordering
> - * @i: value to complement then AND
> - * @v: pointer of type atomic_t
> - *
> - * Atomically complement then AND @i with @v using full ordering.
> - * Return old value.
> - */
> +// Fallback fence omitting duplicate arch_atomic_fetch_andnot() kernel-doc header.
>  static __always_inline int
>  arch_atomic_fetch_andnot(int i, atomic_t *v)
>  {
> @@ -1699,18 +1606,7 @@ arch_atomic_try_cmpxchg_relaxed(atomic_t *v, int *old, int new)
>  #else /* arch_atomic_try_cmpxchg_relaxed */
>  
>  #ifndef arch_atomic_try_cmpxchg_acquire
> -/**
> - * arch_atomic_try_cmpxchg_acquire - Atomic try_cmpxchg with acquire ordering
> - * @v: pointer of type atomic_t
> - * @old: desired old value to match
> - * @new: new value to put in
> - *
> - * Atomically compares @new to *@v, and if equal,
> - * stores @new to *@v, providing acquire ordering.
> - * Returns @true if the cmpxchg operation succeeded,
> - * and false otherwise.  Either way, stores the old
> - * value of *@v to *@old.
> - */
> +// Fallback acquire omitting duplicate arch_atomic_try_cmpxchg_acquire() kernel-doc header.
>  static __always_inline bool
>  arch_atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
>  {
> @@ -1722,18 +1618,7 @@ arch_atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
>  #endif
>  
>  #ifndef arch_atomic_try_cmpxchg_release
> -/**
> - * arch_atomic_try_cmpxchg_release - Atomic try_cmpxchg with release ordering
> - * @v: pointer of type atomic_t
> - * @old: desired old value to match
> - * @new: new value to put in
> - *
> - * Atomically compares @new to *@v, and if equal,
> - * stores @new to *@v, providing release ordering.
> - * Returns @true if the cmpxchg operation succeeded,
> - * and false otherwise.  Either way, stores the old
> - * value of *@v to *@old.
> - */
> +// Fallback release omitting duplicate arch_atomic_try_cmpxchg_release() kernel-doc header.
>  static __always_inline bool
>  arch_atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
>  {
> @@ -1744,18 +1629,7 @@ arch_atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
>  #endif
>  
>  #ifndef arch_atomic_try_cmpxchg
> -/**
> - * arch_atomic_try_cmpxchg - Atomic try_cmpxchg with full ordering
> - * @v: pointer of type atomic_t
> - * @old: desired old value to match
> - * @new: new value to put in
> - *
> - * Atomically compares @new to *@v, and if equal,
> - * stores @new to *@v, providing full ordering.
> - * Returns @true if the cmpxchg operation succeeded,
> - * and false otherwise.  Either way, stores the old
> - * value of *@v to *@old.
> - */
> +// Fallback fence omitting duplicate arch_atomic_try_cmpxchg() kernel-doc header.
>  static __always_inline bool
>  arch_atomic_try_cmpxchg(atomic_t *v, int *old, int new)
>  {
> @@ -1900,15 +1774,7 @@ arch_atomic_add_negative_relaxed(int i, atomic_t *v)
>  #else /* arch_atomic_add_negative_relaxed */
>  
>  #ifndef arch_atomic_add_negative_acquire
> -/**
> - * arch_atomic_add_negative_acquire - Atomic add_negative with acquire ordering
> - * @i: value to add
> - * @v: pointer of type atomic_t
> - *
> - * Atomically add @i with @v using acquire ordering.
> - * Return @true if the result is negative, or @false when
> - * the result is greater than or equal to zero.
> - */
> +// Fallback acquire omitting duplicate arch_atomic_add_negative_acquire() kernel-doc header.
>  static __always_inline bool
>  arch_atomic_add_negative_acquire(int i, atomic_t *v)
>  {
> @@ -1920,15 +1786,7 @@ arch_atomic_add_negative_acquire(int i, atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_add_negative_release
> -/**
> - * arch_atomic_add_negative_release - Atomic add_negative with release ordering
> - * @i: value to add
> - * @v: pointer of type atomic_t
> - *
> - * Atomically add @i with @v using release ordering.
> - * Return @true if the result is negative, or @false when
> - * the result is greater than or equal to zero.
> - */
> +// Fallback release omitting duplicate arch_atomic_add_negative_release() kernel-doc header.
>  static __always_inline bool
>  arch_atomic_add_negative_release(int i, atomic_t *v)
>  {
> @@ -1939,15 +1797,7 @@ arch_atomic_add_negative_release(int i, atomic_t *v)
>  #endif
>  
>  #ifndef arch_atomic_add_negative
> -/**
> - * arch_atomic_add_negative - Atomic add_negative with full ordering
> - * @i: value to add
> - * @v: pointer of type atomic_t
> - *
> - * Atomically add @i with @v using full ordering.
> - * Return @true if the result is negative, or @false when
> - * the result is greater than or equal to zero.
> - */
> +// Fallback fence omitting duplicate arch_atomic_add_negative() kernel-doc header.
>  static __always_inline bool
>  arch_atomic_add_negative(int i, atomic_t *v)
>  {
> @@ -2500,13 +2350,7 @@ arch_atomic64_inc_return_relaxed(atomic64_t *v)
>  #else /* arch_atomic64_inc_return_relaxed */
>  
>  #ifndef arch_atomic64_inc_return_acquire
> -/**
> - * arch_atomic64_inc_return_acquire - Atomic inc with acquire ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically increment @v using acquire ordering.
> - * Return new value.
> - */
> +// Fallback acquire omitting duplicate arch_atomic64_inc_return_acquire() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_inc_return_acquire(atomic64_t *v)
>  {
> @@ -2518,13 +2362,7 @@ arch_atomic64_inc_return_acquire(atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_inc_return_release
> -/**
> - * arch_atomic64_inc_return_release - Atomic inc with release ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically increment @v using release ordering.
> - * Return new value.
> - */
> +// Fallback release omitting duplicate arch_atomic64_inc_return_release() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_inc_return_release(atomic64_t *v)
>  {
> @@ -2535,13 +2373,7 @@ arch_atomic64_inc_return_release(atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_inc_return
> -/**
> - * arch_atomic64_inc_return - Atomic inc with full ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically increment @v using full ordering.
> - * Return new value.
> - */
> +// Fallback fence omitting duplicate arch_atomic64_inc_return() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_inc_return(atomic64_t *v)
>  {
> @@ -2630,13 +2462,7 @@ arch_atomic64_fetch_inc_relaxed(atomic64_t *v)
>  #else /* arch_atomic64_fetch_inc_relaxed */
>  
>  #ifndef arch_atomic64_fetch_inc_acquire
> -/**
> - * arch_atomic64_fetch_inc_acquire - Atomic inc with acquire ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically increment @v using acquire ordering.
> - * Return old value.
> - */
> +// Fallback acquire omitting duplicate arch_atomic64_fetch_inc_acquire() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_fetch_inc_acquire(atomic64_t *v)
>  {
> @@ -2648,13 +2474,7 @@ arch_atomic64_fetch_inc_acquire(atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_fetch_inc_release
> -/**
> - * arch_atomic64_fetch_inc_release - Atomic inc with release ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically increment @v using release ordering.
> - * Return old value.
> - */
> +// Fallback release omitting duplicate arch_atomic64_fetch_inc_release() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_fetch_inc_release(atomic64_t *v)
>  {
> @@ -2665,13 +2485,7 @@ arch_atomic64_fetch_inc_release(atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_fetch_inc
> -/**
> - * arch_atomic64_fetch_inc - Atomic inc with full ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically increment @v using full ordering.
> - * Return old value.
> - */
> +// Fallback fence omitting duplicate arch_atomic64_fetch_inc() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_fetch_inc(atomic64_t *v)
>  {
> @@ -2776,13 +2590,7 @@ arch_atomic64_dec_return_relaxed(atomic64_t *v)
>  #else /* arch_atomic64_dec_return_relaxed */
>  
>  #ifndef arch_atomic64_dec_return_acquire
> -/**
> - * arch_atomic64_dec_return_acquire - Atomic dec with acquire ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically decrement @v using acquire ordering.
> - * Return new value.
> - */
> +// Fallback acquire omitting duplicate arch_atomic64_dec_return_acquire() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_dec_return_acquire(atomic64_t *v)
>  {
> @@ -2794,13 +2602,7 @@ arch_atomic64_dec_return_acquire(atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_dec_return_release
> -/**
> - * arch_atomic64_dec_return_release - Atomic dec with release ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically decrement @v using release ordering.
> - * Return new value.
> - */
> +// Fallback release omitting duplicate arch_atomic64_dec_return_release() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_dec_return_release(atomic64_t *v)
>  {
> @@ -2811,13 +2613,7 @@ arch_atomic64_dec_return_release(atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_dec_return
> -/**
> - * arch_atomic64_dec_return - Atomic dec with full ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically decrement @v using full ordering.
> - * Return new value.
> - */
> +// Fallback fence omitting duplicate arch_atomic64_dec_return() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_dec_return(atomic64_t *v)
>  {
> @@ -2906,13 +2702,7 @@ arch_atomic64_fetch_dec_relaxed(atomic64_t *v)
>  #else /* arch_atomic64_fetch_dec_relaxed */
>  
>  #ifndef arch_atomic64_fetch_dec_acquire
> -/**
> - * arch_atomic64_fetch_dec_acquire - Atomic dec with acquire ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically decrement @v using acquire ordering.
> - * Return old value.
> - */
> +// Fallback acquire omitting duplicate arch_atomic64_fetch_dec_acquire() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_fetch_dec_acquire(atomic64_t *v)
>  {
> @@ -2924,13 +2714,7 @@ arch_atomic64_fetch_dec_acquire(atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_fetch_dec_release
> -/**
> - * arch_atomic64_fetch_dec_release - Atomic dec with release ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically decrement @v using release ordering.
> - * Return old value.
> - */
> +// Fallback release omitting duplicate arch_atomic64_fetch_dec_release() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_fetch_dec_release(atomic64_t *v)
>  {
> @@ -2941,13 +2725,7 @@ arch_atomic64_fetch_dec_release(atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_fetch_dec
> -/**
> - * arch_atomic64_fetch_dec - Atomic dec with full ordering
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically decrement @v using full ordering.
> - * Return old value.
> - */
> +// Fallback fence omitting duplicate arch_atomic64_fetch_dec() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_fetch_dec(atomic64_t *v)
>  {
> @@ -3123,14 +2901,7 @@ arch_atomic64_fetch_andnot_relaxed(s64 i, atomic64_t *v)
>  #else /* arch_atomic64_fetch_andnot_relaxed */
>  
>  #ifndef arch_atomic64_fetch_andnot_acquire
> -/**
> - * arch_atomic64_fetch_andnot_acquire - Atomic andnot with acquire ordering
> - * @i: value to complement then AND
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically complement then AND @i with @v using acquire ordering.
> - * Return old value.
> - */
> +// Fallback acquire omitting duplicate arch_atomic64_fetch_andnot_acquire() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
>  {
> @@ -3142,14 +2913,7 @@ arch_atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_fetch_andnot_release
> -/**
> - * arch_atomic64_fetch_andnot_release - Atomic andnot with release ordering
> - * @i: value to complement then AND
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically complement then AND @i with @v using release ordering.
> - * Return old value.
> - */
> +// Fallback release omitting duplicate arch_atomic64_fetch_andnot_release() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
>  {
> @@ -3160,14 +2924,7 @@ arch_atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_fetch_andnot
> -/**
> - * arch_atomic64_fetch_andnot - Atomic andnot with full ordering
> - * @i: value to complement then AND
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically complement then AND @i with @v using full ordering.
> - * Return old value.
> - */
> +// Fallback fence omitting duplicate arch_atomic64_fetch_andnot() kernel-doc header.
>  static __always_inline s64
>  arch_atomic64_fetch_andnot(s64 i, atomic64_t *v)
>  {
> @@ -3560,18 +3317,7 @@ arch_atomic64_try_cmpxchg_relaxed(atomic64_t *v, s64 *old, s64 new)
>  #else /* arch_atomic64_try_cmpxchg_relaxed */
>  
>  #ifndef arch_atomic64_try_cmpxchg_acquire
> -/**
> - * arch_atomic64_try_cmpxchg_acquire - Atomic try_cmpxchg with acquire ordering
> - * @v: pointer of type atomic64_t
> - * @old: desired old value to match
> - * @new: new value to put in
> - *
> - * Atomically compares @new to *@v, and if equal,
> - * stores @new to *@v, providing acquire ordering.
> - * Returns @true if the cmpxchg operation succeeded,
> - * and false otherwise.  Either way, stores the old
> - * value of *@v to *@old.
> - */
> +// Fallback acquire omitting duplicate arch_atomic64_try_cmpxchg_acquire() kernel-doc header.
>  static __always_inline bool
>  arch_atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
>  {
> @@ -3583,18 +3329,7 @@ arch_atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
>  #endif
>  
>  #ifndef arch_atomic64_try_cmpxchg_release
> -/**
> - * arch_atomic64_try_cmpxchg_release - Atomic try_cmpxchg with release ordering
> - * @v: pointer of type atomic64_t
> - * @old: desired old value to match
> - * @new: new value to put in
> - *
> - * Atomically compares @new to *@v, and if equal,
> - * stores @new to *@v, providing release ordering.
> - * Returns @true if the cmpxchg operation succeeded,
> - * and false otherwise.  Either way, stores the old
> - * value of *@v to *@old.
> - */
> +// Fallback release omitting duplicate arch_atomic64_try_cmpxchg_release() kernel-doc header.
>  static __always_inline bool
>  arch_atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
>  {
> @@ -3605,18 +3340,7 @@ arch_atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
>  #endif
>  
>  #ifndef arch_atomic64_try_cmpxchg
> -/**
> - * arch_atomic64_try_cmpxchg - Atomic try_cmpxchg with full ordering
> - * @v: pointer of type atomic64_t
> - * @old: desired old value to match
> - * @new: new value to put in
> - *
> - * Atomically compares @new to *@v, and if equal,
> - * stores @new to *@v, providing full ordering.
> - * Returns @true if the cmpxchg operation succeeded,
> - * and false otherwise.  Either way, stores the old
> - * value of *@v to *@old.
> - */
> +// Fallback fence omitting duplicate arch_atomic64_try_cmpxchg() kernel-doc header.
>  static __always_inline bool
>  arch_atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new)
>  {
> @@ -3761,15 +3485,7 @@ arch_atomic64_add_negative_relaxed(s64 i, atomic64_t *v)
>  #else /* arch_atomic64_add_negative_relaxed */
>  
>  #ifndef arch_atomic64_add_negative_acquire
> -/**
> - * arch_atomic64_add_negative_acquire - Atomic add_negative with acquire ordering
> - * @i: value to add
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically add @i with @v using acquire ordering.
> - * Return @true if the result is negative, or @false when
> - * the result is greater than or equal to zero.
> - */
> +// Fallback acquire omitting duplicate arch_atomic64_add_negative_acquire() kernel-doc header.
>  static __always_inline bool
>  arch_atomic64_add_negative_acquire(s64 i, atomic64_t *v)
>  {
> @@ -3781,15 +3497,7 @@ arch_atomic64_add_negative_acquire(s64 i, atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_add_negative_release
> -/**
> - * arch_atomic64_add_negative_release - Atomic add_negative with release ordering
> - * @i: value to add
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically add @i with @v using release ordering.
> - * Return @true if the result is negative, or @false when
> - * the result is greater than or equal to zero.
> - */
> +// Fallback release omitting duplicate arch_atomic64_add_negative_release() kernel-doc header.
>  static __always_inline bool
>  arch_atomic64_add_negative_release(s64 i, atomic64_t *v)
>  {
> @@ -3800,15 +3508,7 @@ arch_atomic64_add_negative_release(s64 i, atomic64_t *v)
>  #endif
>  
>  #ifndef arch_atomic64_add_negative
> -/**
> - * arch_atomic64_add_negative - Atomic add_negative with full ordering
> - * @i: value to add
> - * @v: pointer of type atomic64_t
> - *
> - * Atomically add @i with @v using full ordering.
> - * Return @true if the result is negative, or @false when
> - * the result is greater than or equal to zero.
> - */
> +// Fallback fence omitting duplicate arch_atomic64_add_negative() kernel-doc header.
>  static __always_inline bool
>  arch_atomic64_add_negative(s64 i, atomic64_t *v)
>  {
> @@ -3958,4 +3658,4 @@ arch_atomic64_dec_if_positive(atomic64_t *v)
>  #endif
>  
>  #endif /* _LINUX_ATOMIC_FALLBACK_H */
> -// 7c2c97cd48cf9c672efc44b9fed5a37b8970dde4
> +// 9bf9febc5288ed9539d1b3cfbbc6e36743b74c3b
> diff --git a/scripts/atomic/chkdup.sh b/scripts/atomic/chkdup.sh
> new file mode 100644
> index 000000000000..04bb4f5c5c34
> --- /dev/null
> +++ b/scripts/atomic/chkdup.sh
> @@ -0,0 +1,27 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Check to see if the specified atomic is already in use.  This is
> +# done by keeping filenames in the temporary directory specified by the
> +# environment variable T.
> +#
> +# Usage:
> +#	chkdup.sh name fallback
> +#
> +# The "name" argument is the name of the function to be generated, and
> +# the "fallback" argument is the name of the fallback script that is
> +# doing the generation.
> +#
> +# If the function is a duplicate, output a comment saying so and
> +# exit with non-zero (error) status.  Otherwise exit successfully
> +#
> +# If the function is a duplicate, output a comment saying so and
> +# exit with non-zero (error) status.  Otherwise exit successfully.
> +
> +if test -f ${T}/${1}
> +then
> +	echo // Fallback ${2} omitting duplicate "${1}()" kernel-doc header.
> +	exit 1
> +fi
> +touch ${T}/${1}
> +exit 0
> diff --git a/scripts/atomic/fallbacks/acquire b/scripts/atomic/fallbacks/acquire
> index 08fc6c30a9ef..a349935ac7fe 100755
> --- a/scripts/atomic/fallbacks/acquire
> +++ b/scripts/atomic/fallbacks/acquire
> @@ -1,5 +1,8 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}${name}${sfx}_acquire acquire
> +then
>  acqrel=acquire
>  . ${ATOMICDIR}/acqrel.sh
> +fi
>  cat << EOF
>  static __always_inline ${ret}
>  arch_${atomic}_${pfx}${name}${sfx}_acquire(${params})
> diff --git a/scripts/atomic/fallbacks/add_negative b/scripts/atomic/fallbacks/add_negative
> index c032e8bec6e2..b105fdfe8fd1 100755
> --- a/scripts/atomic/fallbacks/add_negative
> +++ b/scripts/atomic/fallbacks/add_negative
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_add_negative${order} add_negative
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_add_negative${order} - Add and test if negative
> @@ -7,6 +9,9 @@ cat <<EOF
>   * Atomically adds @i to @v and returns @true if the result is negative,
>   * or @false when the result is greater than or equal to zero.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline bool
>  arch_${atomic}_add_negative${order}(${int} i, ${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/add_unless b/scripts/atomic/fallbacks/add_unless
> index 650fee935aed..d72d382e3757 100755
> --- a/scripts/atomic/fallbacks/add_unless
> +++ b/scripts/atomic/fallbacks/add_unless
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_add_unless add_unless
> +then
>  cat << EOF
>  /**
>   * arch_${atomic}_add_unless - add unless the number is already a given value
> @@ -8,6 +10,9 @@ cat << EOF
>   * Atomically adds @a to @v, if @v was not already @u.
>   * Returns @true if the addition was done.
>   */
> +EOF
> +fi
> +cat << EOF
>  static __always_inline bool
>  arch_${atomic}_add_unless(${atomic}_t *v, ${int} a, ${int} u)
>  {
> diff --git a/scripts/atomic/fallbacks/andnot b/scripts/atomic/fallbacks/andnot
> index 9fbc0ce75a7c..57b2a187374a 100755
> --- a/scripts/atomic/fallbacks/andnot
> +++ b/scripts/atomic/fallbacks/andnot
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}andnot${sfx}${order} andnot
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_${pfx}andnot${sfx}${order} - Atomic and-not
> @@ -7,6 +9,9 @@ cat <<EOF
>   * Atomically and-not @i with @v using ${docbook_order} ordering.
>   * returning ${docbook_oldnew} value.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline ${ret}
>  arch_${atomic}_${pfx}andnot${sfx}${order}(${int} i, ${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/dec b/scripts/atomic/fallbacks/dec
> index e99c8edd36a3..e44d3eb96d2b 100755
> --- a/scripts/atomic/fallbacks/dec
> +++ b/scripts/atomic/fallbacks/dec
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}dec${sfx}${order} dec
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_${pfx}dec${sfx}${order} - Atomic decrement
> @@ -6,6 +8,9 @@ cat <<EOF
>   * Atomically decrement @v with ${docbook_order} ordering,
>   * returning ${docbook_oldnew} value.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline ${ret}
>  arch_${atomic}_${pfx}dec${sfx}${order}(${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/dec_and_test b/scripts/atomic/fallbacks/dec_and_test
> index 3720896b1afc..94f5a6d4827c 100755
> --- a/scripts/atomic/fallbacks/dec_and_test
> +++ b/scripts/atomic/fallbacks/dec_and_test
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_dec_and_test dec_and_test
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_dec_and_test - decrement and test
> @@ -7,6 +9,9 @@ cat <<EOF
>   * returns @true if the result is 0, or @false for all other
>   * cases.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline bool
>  arch_${atomic}_dec_and_test(${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/dec_if_positive b/scripts/atomic/fallbacks/dec_if_positive
> index dedbdbc1487d..e27eb71dd1b2 100755
> --- a/scripts/atomic/fallbacks/dec_if_positive
> +++ b/scripts/atomic/fallbacks/dec_if_positive
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_dec_if_positive dec_if_positive
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_dec_if_positive - Atomic decrement if old value is positive
> @@ -9,6 +11,9 @@ cat <<EOF
>   * there @v will not be decremented, but -4 will be returned.  As a result,
>   * if the return value is non-negative, then the value was in fact decremented.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline ${ret}
>  arch_${atomic}_dec_if_positive(${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/dec_unless_positive b/scripts/atomic/fallbacks/dec_unless_positive
> index c3d01d201c63..ee00fffc5f11 100755
> --- a/scripts/atomic/fallbacks/dec_unless_positive
> +++ b/scripts/atomic/fallbacks/dec_unless_positive
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_dec_unless_positive dec_unless_positive
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_dec_unless_positive - Atomic decrement if old value is non-positive
> @@ -7,6 +9,9 @@ cat <<EOF
>   * than or equal to zero.  Return @true if the decrement happened and
>   * @false otherwise.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline bool
>  arch_${atomic}_dec_unless_positive(${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/fence b/scripts/atomic/fallbacks/fence
> index 975855dfba25..f4901343cd2b 100755
> --- a/scripts/atomic/fallbacks/fence
> +++ b/scripts/atomic/fallbacks/fence
> @@ -1,5 +1,8 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}${name}${sfx} fence
> +then
>  acqrel=full
>  . ${ATOMICDIR}/acqrel.sh
> +fi
>  cat <<EOF
>  static __always_inline ${ret}
>  arch_${atomic}_${pfx}${name}${sfx}(${params})
> diff --git a/scripts/atomic/fallbacks/fetch_add_unless b/scripts/atomic/fallbacks/fetch_add_unless
> index a1692df0d514..ec583d340785 100755
> --- a/scripts/atomic/fallbacks/fetch_add_unless
> +++ b/scripts/atomic/fallbacks/fetch_add_unless
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_fetch_add_unless fetch_add_unless
> +then
>  cat << EOF
>  /**
>   * arch_${atomic}_fetch_add_unless - add unless the number is already a given value
> @@ -8,6 +10,9 @@ cat << EOF
>   * Atomically adds @a to @v, so long as @v was not already @u.
>   * Returns original value of @v.
>   */
> +EOF
> +fi
> +cat << EOF
>  static __always_inline ${int}
>  arch_${atomic}_fetch_add_unless(${atomic}_t *v, ${int} a, ${int} u)
>  {
> diff --git a/scripts/atomic/fallbacks/inc b/scripts/atomic/fallbacks/inc
> index 3f2c0730cd0c..bb1d5ea6846c 100755
> --- a/scripts/atomic/fallbacks/inc
> +++ b/scripts/atomic/fallbacks/inc
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}inc${sfx}${order} inc
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_${pfx}inc${sfx}${order} - Atomic increment
> @@ -6,6 +8,9 @@ cat <<EOF
>   * Atomically increment @v with ${docbook_order} ordering,
>   * returning ${docbook_oldnew} value.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline ${ret}
>  arch_${atomic}_${pfx}inc${sfx}${order}(${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/inc_and_test b/scripts/atomic/fallbacks/inc_and_test
> index cc3ac1dde508..dd74f6a5ca4a 100755
> --- a/scripts/atomic/fallbacks/inc_and_test
> +++ b/scripts/atomic/fallbacks/inc_and_test
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_inc_and_test inc_and_test
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_inc_and_test - increment and test
> @@ -7,6 +9,9 @@ cat <<EOF
>   * and returns @true if the result is zero, or @false for all
>   * other cases.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline bool
>  arch_${atomic}_inc_and_test(${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/inc_not_zero b/scripts/atomic/fallbacks/inc_not_zero
> index 891fa3c057f6..38e2c13dab62 100755
> --- a/scripts/atomic/fallbacks/inc_not_zero
> +++ b/scripts/atomic/fallbacks/inc_not_zero
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_inc_not_zero inc_not_zero
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_inc_not_zero - increment unless the number is zero
> @@ -6,6 +8,9 @@ cat <<EOF
>   * Atomically increments @v by 1, if @v is non-zero.
>   * Returns @true if the increment was done.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline bool
>  arch_${atomic}_inc_not_zero(${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/inc_unless_negative b/scripts/atomic/fallbacks/inc_unless_negative
> index 98830b0dcdb1..2dc853c4e5b9 100755
> --- a/scripts/atomic/fallbacks/inc_unless_negative
> +++ b/scripts/atomic/fallbacks/inc_unless_negative
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_inc_unless_negative inc_unless_negative
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_inc_unless_negative - Atomic increment if old value is non-negative
> @@ -7,6 +9,9 @@ cat <<EOF
>   * than or equal to zero.  Return @true if the increment happened and
>   * @false otherwise.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline bool
>  arch_${atomic}_inc_unless_negative(${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/read_acquire b/scripts/atomic/fallbacks/read_acquire
> index 779f40c07018..680cd43080cb 100755
> --- a/scripts/atomic/fallbacks/read_acquire
> +++ b/scripts/atomic/fallbacks/read_acquire
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_read_acquire read_acquire
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_read_acquire - Atomic load acquire
> @@ -6,6 +8,9 @@ cat <<EOF
>   * Atomically load from *@v with acquire ordering, returning the value
>   * loaded.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline ${ret}
>  arch_${atomic}_read_acquire(const ${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/release b/scripts/atomic/fallbacks/release
> index bce3a1cbd497..a1604df66ece 100755
> --- a/scripts/atomic/fallbacks/release
> +++ b/scripts/atomic/fallbacks/release
> @@ -1,5 +1,8 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}${name}${sfx}_release release
> +then
>  acqrel=release
>  . ${ATOMICDIR}/acqrel.sh
> +fi
>  cat <<EOF
>  static __always_inline ${ret}
>  arch_${atomic}_${pfx}${name}${sfx}_release(${params})
> diff --git a/scripts/atomic/fallbacks/set_release b/scripts/atomic/fallbacks/set_release
> index 46effb6203e5..2a65d3b29f4b 100755
> --- a/scripts/atomic/fallbacks/set_release
> +++ b/scripts/atomic/fallbacks/set_release
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_set_release set_release
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_set_release - Atomic store release
> @@ -6,6 +8,9 @@ cat <<EOF
>   *
>   * Atomically store @i into *@v with release ordering.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline void
>  arch_${atomic}_set_release(${atomic}_t *v, ${int} i)
>  {
> diff --git a/scripts/atomic/fallbacks/sub_and_test b/scripts/atomic/fallbacks/sub_and_test
> index 204282e260ea..0397b0e92192 100755
> --- a/scripts/atomic/fallbacks/sub_and_test
> +++ b/scripts/atomic/fallbacks/sub_and_test
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_sub_and_test sub_and_test
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_sub_and_test - subtract value from variable and test result
> @@ -8,6 +10,9 @@ cat <<EOF
>   * @true if the result is zero, or @false for all
>   * other cases.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline bool
>  arch_${atomic}_sub_and_test(${int} i, ${atomic}_t *v)
>  {
> diff --git a/scripts/atomic/fallbacks/try_cmpxchg b/scripts/atomic/fallbacks/try_cmpxchg
> index baf7412f9bf4..e08c5962dd83 100755
> --- a/scripts/atomic/fallbacks/try_cmpxchg
> +++ b/scripts/atomic/fallbacks/try_cmpxchg
> @@ -1,3 +1,5 @@
> +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_try_cmpxchg${order} try_cmpxchg
> +then
>  cat <<EOF
>  /**
>   * arch_${atomic}_try_cmpxchg${order} - Atomic cmpxchg with bool return value
> @@ -9,6 +11,9 @@ cat <<EOF
>   * providing ${docbook_order} ordering.
>   * Returns @true if the cmpxchg operation succeeded, and false otherwise.
>   */
> +EOF
> +fi
> +cat <<EOF
>  static __always_inline bool
>  arch_${atomic}_try_cmpxchg${order}(${atomic}_t *v, ${int} *old, ${int} new)
>  {
> diff --git a/scripts/atomic/gen-atomics.sh b/scripts/atomic/gen-atomics.sh
> index 5b98a8307693..69bf3754df5a 100755
> --- a/scripts/atomic/gen-atomics.sh
> +++ b/scripts/atomic/gen-atomics.sh
> @@ -3,6 +3,10 @@
>  #
>  # Generate atomic headers
>  
> +T="`mktemp -d ${TMPDIR-/tmp}/gen-atomics.sh.XXXXXX`"
> +trap 'rm -rf $T' 0
> +export T
> +
>  ATOMICDIR=$(dirname $0)
>  ATOMICTBL=${ATOMICDIR}/atomics.tbl
>  LINUXDIR=${ATOMICDIR}/../..
> -- 
> 2.40.1
>
  
Paul E. McKenney May 11, 2023, 7:12 p.m. UTC | #2
On Thu, May 11, 2023 at 06:10:00PM +0100, Mark Rutland wrote:
> Hi Paul
> 
> On Wed, May 10, 2023 at 11:17:16AM -0700, Paul E. McKenney wrote:
> > The gen-atomics.sh script currently generates 42 duplicate definitions:
> > 
> > 	arch_atomic64_add_negative
> > 	arch_atomic64_add_negative_acquire
> > 	arch_atomic64_add_negative_release
> 
> 	[...]
> 
> > These duplicates are presumably to handle different architectures
> > generating hand-coded definitions for different subsets of the atomic
> > operations.
> 
> Yup, for each FULL/ACQUIRE/RELEASE/RELAXED variant of each op, we allow the
> archtiecture to choose between:
> 
> * Providing the ordering variant directly
> * Providing the FULL ordering variant only
> * Providing the RELAXED ordering variant only
> * Providing an equivalent op that we can build from

Thank you for the explanation!

> > However, generating duplicate kernel-doc headers is undesirable.
> 
> Understood -- I hadn't understood that duplication was a problem when this was
> originally written.

And neither did I!!!

Instead Akira kindly ran "make htmldocs" on my original attempt and let
me know of the breakage.

> The way this is currently done is largely an artifact of our ifdeffery (and the
> kerneldoc for fallbacks living inthe fallback templates), and I think we can
> fix both of those.

Fair enough!

> > Therefore, generate only the first kernel-doc definition in a group
> > of duplicates.  A comment indicates the name of the function and the
> > fallback script that generated it.
> 
> I'm not keen on this approach, especially with the chkdup.sh script -- it feels
> like we're working around an underlying structural issue.

I freely admit that I was taking the most expedient path.  ;-)

> I think that we can restructure the ifdeffery so that each ordering variant
> gets its own ifdeffery, and then we could place the kerneldoc immediately above
> that, e.g.
> 
> 	/**
> 	 * arch_atomic_inc_return_release()
> 	 *
> 	 * [ full kerneldoc block here ]
> 	 */
> 	#if defined(arch_atomic_inc_return_release)
> 	/* defined in arch code */
> 	#elif defined(arch_atomic_inc_return_relaxed)
> 	[ define in terms of arch_atomic_inc_return_relaxed ]
> 	#elif defined(arch_atomic_inc_return)
> 	[ define in terms of arch_atomic_inc_return ]
> 	#else
> 	[ define in terms of arch_atomic_fetch_inc_release ]
> 	#endif
> 
> ... with similar for the mandatory ops that each arch must provide, e.g.
> 
> 	/**
> 	 * arch_atomic_or()
> 	 *
> 	 * [ full kerneldoc block here ]
> 	 */
> 	/* arch_atomic_or() is mandatory -- architectures must define it! */
> 
> I had a go at that restructuring today, and while local build testing indicates
> I haven't got it quite right, I think it's possible:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> 
> Does that sound ok to you?

At first glance, it appears that your "TODO" locations have the same
information that I was using, so it should not be hard for me to adapt the
current kernel-doc generation to your new scheme.  (Famous last words!)

Plus having the kernel-doc generation all in one place does have some
serious attractions.

I will continue maintaining my current stack, but would of course be
happy to port it on top of your refactoring.  If it turns out that
the refactoring will take a long time, we can discuss what to do in
the meantime.  But here is hoping that the refactoring goes smoothly!
That would be easier all around.  ;-)

							Thanx, Paul

> Thanks,
> Mark.
> 
> > Reported-by: Akira Yokosawa <akiyks@gmail.com>
> > Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> > Cc: Will Deacon <will@kernel.org>
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Cc: Boqun Feng <boqun.feng@gmail.com>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > ---
> >  include/linux/atomic/atomic-arch-fallback.h  | 386 +++----------------
> >  scripts/atomic/chkdup.sh                     |  27 ++
> >  scripts/atomic/fallbacks/acquire             |   3 +
> >  scripts/atomic/fallbacks/add_negative        |   5 +
> >  scripts/atomic/fallbacks/add_unless          |   5 +
> >  scripts/atomic/fallbacks/andnot              |   5 +
> >  scripts/atomic/fallbacks/dec                 |   5 +
> >  scripts/atomic/fallbacks/dec_and_test        |   5 +
> >  scripts/atomic/fallbacks/dec_if_positive     |   5 +
> >  scripts/atomic/fallbacks/dec_unless_positive |   5 +
> >  scripts/atomic/fallbacks/fence               |   3 +
> >  scripts/atomic/fallbacks/fetch_add_unless    |   5 +
> >  scripts/atomic/fallbacks/inc                 |   5 +
> >  scripts/atomic/fallbacks/inc_and_test        |   5 +
> >  scripts/atomic/fallbacks/inc_not_zero        |   5 +
> >  scripts/atomic/fallbacks/inc_unless_negative |   5 +
> >  scripts/atomic/fallbacks/read_acquire        |   5 +
> >  scripts/atomic/fallbacks/release             |   3 +
> >  scripts/atomic/fallbacks/set_release         |   5 +
> >  scripts/atomic/fallbacks/sub_and_test        |   5 +
> >  scripts/atomic/fallbacks/try_cmpxchg         |   5 +
> >  scripts/atomic/gen-atomics.sh                |   4 +
> >  22 files changed, 163 insertions(+), 343 deletions(-)
> >  create mode 100644 scripts/atomic/chkdup.sh
> > 
> > diff --git a/include/linux/atomic/atomic-arch-fallback.h b/include/linux/atomic/atomic-arch-fallback.h
> > index 41aa94f0aacd..2d56726f8662 100644
> > --- a/include/linux/atomic/atomic-arch-fallback.h
> > +++ b/include/linux/atomic/atomic-arch-fallback.h
> > @@ -639,13 +639,7 @@ arch_atomic_inc_return_relaxed(atomic_t *v)
> >  #else /* arch_atomic_inc_return_relaxed */
> >  
> >  #ifndef arch_atomic_inc_return_acquire
> > -/**
> > - * arch_atomic_inc_return_acquire - Atomic inc with acquire ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically increment @v using acquire ordering.
> > - * Return new value.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic_inc_return_acquire() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_inc_return_acquire(atomic_t *v)
> >  {
> > @@ -657,13 +651,7 @@ arch_atomic_inc_return_acquire(atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_inc_return_release
> > -/**
> > - * arch_atomic_inc_return_release - Atomic inc with release ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically increment @v using release ordering.
> > - * Return new value.
> > - */
> > +// Fallback release omitting duplicate arch_atomic_inc_return_release() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_inc_return_release(atomic_t *v)
> >  {
> > @@ -674,13 +662,7 @@ arch_atomic_inc_return_release(atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_inc_return
> > -/**
> > - * arch_atomic_inc_return - Atomic inc with full ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically increment @v using full ordering.
> > - * Return new value.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic_inc_return() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_inc_return(atomic_t *v)
> >  {
> > @@ -769,13 +751,7 @@ arch_atomic_fetch_inc_relaxed(atomic_t *v)
> >  #else /* arch_atomic_fetch_inc_relaxed */
> >  
> >  #ifndef arch_atomic_fetch_inc_acquire
> > -/**
> > - * arch_atomic_fetch_inc_acquire - Atomic inc with acquire ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically increment @v using acquire ordering.
> > - * Return old value.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic_fetch_inc_acquire() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_fetch_inc_acquire(atomic_t *v)
> >  {
> > @@ -787,13 +763,7 @@ arch_atomic_fetch_inc_acquire(atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_fetch_inc_release
> > -/**
> > - * arch_atomic_fetch_inc_release - Atomic inc with release ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically increment @v using release ordering.
> > - * Return old value.
> > - */
> > +// Fallback release omitting duplicate arch_atomic_fetch_inc_release() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_fetch_inc_release(atomic_t *v)
> >  {
> > @@ -804,13 +774,7 @@ arch_atomic_fetch_inc_release(atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_fetch_inc
> > -/**
> > - * arch_atomic_fetch_inc - Atomic inc with full ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically increment @v using full ordering.
> > - * Return old value.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic_fetch_inc() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_fetch_inc(atomic_t *v)
> >  {
> > @@ -915,13 +879,7 @@ arch_atomic_dec_return_relaxed(atomic_t *v)
> >  #else /* arch_atomic_dec_return_relaxed */
> >  
> >  #ifndef arch_atomic_dec_return_acquire
> > -/**
> > - * arch_atomic_dec_return_acquire - Atomic dec with acquire ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically decrement @v using acquire ordering.
> > - * Return new value.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic_dec_return_acquire() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_dec_return_acquire(atomic_t *v)
> >  {
> > @@ -933,13 +891,7 @@ arch_atomic_dec_return_acquire(atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_dec_return_release
> > -/**
> > - * arch_atomic_dec_return_release - Atomic dec with release ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically decrement @v using release ordering.
> > - * Return new value.
> > - */
> > +// Fallback release omitting duplicate arch_atomic_dec_return_release() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_dec_return_release(atomic_t *v)
> >  {
> > @@ -950,13 +902,7 @@ arch_atomic_dec_return_release(atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_dec_return
> > -/**
> > - * arch_atomic_dec_return - Atomic dec with full ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically decrement @v using full ordering.
> > - * Return new value.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic_dec_return() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_dec_return(atomic_t *v)
> >  {
> > @@ -1045,13 +991,7 @@ arch_atomic_fetch_dec_relaxed(atomic_t *v)
> >  #else /* arch_atomic_fetch_dec_relaxed */
> >  
> >  #ifndef arch_atomic_fetch_dec_acquire
> > -/**
> > - * arch_atomic_fetch_dec_acquire - Atomic dec with acquire ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically decrement @v using acquire ordering.
> > - * Return old value.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic_fetch_dec_acquire() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_fetch_dec_acquire(atomic_t *v)
> >  {
> > @@ -1063,13 +1003,7 @@ arch_atomic_fetch_dec_acquire(atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_fetch_dec_release
> > -/**
> > - * arch_atomic_fetch_dec_release - Atomic dec with release ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically decrement @v using release ordering.
> > - * Return old value.
> > - */
> > +// Fallback release omitting duplicate arch_atomic_fetch_dec_release() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_fetch_dec_release(atomic_t *v)
> >  {
> > @@ -1080,13 +1014,7 @@ arch_atomic_fetch_dec_release(atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_fetch_dec
> > -/**
> > - * arch_atomic_fetch_dec - Atomic dec with full ordering
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically decrement @v using full ordering.
> > - * Return old value.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic_fetch_dec() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_fetch_dec(atomic_t *v)
> >  {
> > @@ -1262,14 +1190,7 @@ arch_atomic_fetch_andnot_relaxed(int i, atomic_t *v)
> >  #else /* arch_atomic_fetch_andnot_relaxed */
> >  
> >  #ifndef arch_atomic_fetch_andnot_acquire
> > -/**
> > - * arch_atomic_fetch_andnot_acquire - Atomic andnot with acquire ordering
> > - * @i: value to complement then AND
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically complement then AND @i with @v using acquire ordering.
> > - * Return old value.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic_fetch_andnot_acquire() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_fetch_andnot_acquire(int i, atomic_t *v)
> >  {
> > @@ -1281,14 +1202,7 @@ arch_atomic_fetch_andnot_acquire(int i, atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_fetch_andnot_release
> > -/**
> > - * arch_atomic_fetch_andnot_release - Atomic andnot with release ordering
> > - * @i: value to complement then AND
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically complement then AND @i with @v using release ordering.
> > - * Return old value.
> > - */
> > +// Fallback release omitting duplicate arch_atomic_fetch_andnot_release() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_fetch_andnot_release(int i, atomic_t *v)
> >  {
> > @@ -1299,14 +1213,7 @@ arch_atomic_fetch_andnot_release(int i, atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_fetch_andnot
> > -/**
> > - * arch_atomic_fetch_andnot - Atomic andnot with full ordering
> > - * @i: value to complement then AND
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically complement then AND @i with @v using full ordering.
> > - * Return old value.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic_fetch_andnot() kernel-doc header.
> >  static __always_inline int
> >  arch_atomic_fetch_andnot(int i, atomic_t *v)
> >  {
> > @@ -1699,18 +1606,7 @@ arch_atomic_try_cmpxchg_relaxed(atomic_t *v, int *old, int new)
> >  #else /* arch_atomic_try_cmpxchg_relaxed */
> >  
> >  #ifndef arch_atomic_try_cmpxchg_acquire
> > -/**
> > - * arch_atomic_try_cmpxchg_acquire - Atomic try_cmpxchg with acquire ordering
> > - * @v: pointer of type atomic_t
> > - * @old: desired old value to match
> > - * @new: new value to put in
> > - *
> > - * Atomically compares @new to *@v, and if equal,
> > - * stores @new to *@v, providing acquire ordering.
> > - * Returns @true if the cmpxchg operation succeeded,
> > - * and false otherwise.  Either way, stores the old
> > - * value of *@v to *@old.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic_try_cmpxchg_acquire() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
> >  {
> > @@ -1722,18 +1618,7 @@ arch_atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
> >  #endif
> >  
> >  #ifndef arch_atomic_try_cmpxchg_release
> > -/**
> > - * arch_atomic_try_cmpxchg_release - Atomic try_cmpxchg with release ordering
> > - * @v: pointer of type atomic_t
> > - * @old: desired old value to match
> > - * @new: new value to put in
> > - *
> > - * Atomically compares @new to *@v, and if equal,
> > - * stores @new to *@v, providing release ordering.
> > - * Returns @true if the cmpxchg operation succeeded,
> > - * and false otherwise.  Either way, stores the old
> > - * value of *@v to *@old.
> > - */
> > +// Fallback release omitting duplicate arch_atomic_try_cmpxchg_release() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
> >  {
> > @@ -1744,18 +1629,7 @@ arch_atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
> >  #endif
> >  
> >  #ifndef arch_atomic_try_cmpxchg
> > -/**
> > - * arch_atomic_try_cmpxchg - Atomic try_cmpxchg with full ordering
> > - * @v: pointer of type atomic_t
> > - * @old: desired old value to match
> > - * @new: new value to put in
> > - *
> > - * Atomically compares @new to *@v, and if equal,
> > - * stores @new to *@v, providing full ordering.
> > - * Returns @true if the cmpxchg operation succeeded,
> > - * and false otherwise.  Either way, stores the old
> > - * value of *@v to *@old.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic_try_cmpxchg() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic_try_cmpxchg(atomic_t *v, int *old, int new)
> >  {
> > @@ -1900,15 +1774,7 @@ arch_atomic_add_negative_relaxed(int i, atomic_t *v)
> >  #else /* arch_atomic_add_negative_relaxed */
> >  
> >  #ifndef arch_atomic_add_negative_acquire
> > -/**
> > - * arch_atomic_add_negative_acquire - Atomic add_negative with acquire ordering
> > - * @i: value to add
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically add @i with @v using acquire ordering.
> > - * Return @true if the result is negative, or @false when
> > - * the result is greater than or equal to zero.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic_add_negative_acquire() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic_add_negative_acquire(int i, atomic_t *v)
> >  {
> > @@ -1920,15 +1786,7 @@ arch_atomic_add_negative_acquire(int i, atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_add_negative_release
> > -/**
> > - * arch_atomic_add_negative_release - Atomic add_negative with release ordering
> > - * @i: value to add
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically add @i with @v using release ordering.
> > - * Return @true if the result is negative, or @false when
> > - * the result is greater than or equal to zero.
> > - */
> > +// Fallback release omitting duplicate arch_atomic_add_negative_release() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic_add_negative_release(int i, atomic_t *v)
> >  {
> > @@ -1939,15 +1797,7 @@ arch_atomic_add_negative_release(int i, atomic_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic_add_negative
> > -/**
> > - * arch_atomic_add_negative - Atomic add_negative with full ordering
> > - * @i: value to add
> > - * @v: pointer of type atomic_t
> > - *
> > - * Atomically add @i with @v using full ordering.
> > - * Return @true if the result is negative, or @false when
> > - * the result is greater than or equal to zero.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic_add_negative() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic_add_negative(int i, atomic_t *v)
> >  {
> > @@ -2500,13 +2350,7 @@ arch_atomic64_inc_return_relaxed(atomic64_t *v)
> >  #else /* arch_atomic64_inc_return_relaxed */
> >  
> >  #ifndef arch_atomic64_inc_return_acquire
> > -/**
> > - * arch_atomic64_inc_return_acquire - Atomic inc with acquire ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically increment @v using acquire ordering.
> > - * Return new value.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic64_inc_return_acquire() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_inc_return_acquire(atomic64_t *v)
> >  {
> > @@ -2518,13 +2362,7 @@ arch_atomic64_inc_return_acquire(atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_inc_return_release
> > -/**
> > - * arch_atomic64_inc_return_release - Atomic inc with release ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically increment @v using release ordering.
> > - * Return new value.
> > - */
> > +// Fallback release omitting duplicate arch_atomic64_inc_return_release() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_inc_return_release(atomic64_t *v)
> >  {
> > @@ -2535,13 +2373,7 @@ arch_atomic64_inc_return_release(atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_inc_return
> > -/**
> > - * arch_atomic64_inc_return - Atomic inc with full ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically increment @v using full ordering.
> > - * Return new value.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic64_inc_return() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_inc_return(atomic64_t *v)
> >  {
> > @@ -2630,13 +2462,7 @@ arch_atomic64_fetch_inc_relaxed(atomic64_t *v)
> >  #else /* arch_atomic64_fetch_inc_relaxed */
> >  
> >  #ifndef arch_atomic64_fetch_inc_acquire
> > -/**
> > - * arch_atomic64_fetch_inc_acquire - Atomic inc with acquire ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically increment @v using acquire ordering.
> > - * Return old value.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic64_fetch_inc_acquire() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_fetch_inc_acquire(atomic64_t *v)
> >  {
> > @@ -2648,13 +2474,7 @@ arch_atomic64_fetch_inc_acquire(atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_fetch_inc_release
> > -/**
> > - * arch_atomic64_fetch_inc_release - Atomic inc with release ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically increment @v using release ordering.
> > - * Return old value.
> > - */
> > +// Fallback release omitting duplicate arch_atomic64_fetch_inc_release() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_fetch_inc_release(atomic64_t *v)
> >  {
> > @@ -2665,13 +2485,7 @@ arch_atomic64_fetch_inc_release(atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_fetch_inc
> > -/**
> > - * arch_atomic64_fetch_inc - Atomic inc with full ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically increment @v using full ordering.
> > - * Return old value.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic64_fetch_inc() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_fetch_inc(atomic64_t *v)
> >  {
> > @@ -2776,13 +2590,7 @@ arch_atomic64_dec_return_relaxed(atomic64_t *v)
> >  #else /* arch_atomic64_dec_return_relaxed */
> >  
> >  #ifndef arch_atomic64_dec_return_acquire
> > -/**
> > - * arch_atomic64_dec_return_acquire - Atomic dec with acquire ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically decrement @v using acquire ordering.
> > - * Return new value.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic64_dec_return_acquire() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_dec_return_acquire(atomic64_t *v)
> >  {
> > @@ -2794,13 +2602,7 @@ arch_atomic64_dec_return_acquire(atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_dec_return_release
> > -/**
> > - * arch_atomic64_dec_return_release - Atomic dec with release ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically decrement @v using release ordering.
> > - * Return new value.
> > - */
> > +// Fallback release omitting duplicate arch_atomic64_dec_return_release() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_dec_return_release(atomic64_t *v)
> >  {
> > @@ -2811,13 +2613,7 @@ arch_atomic64_dec_return_release(atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_dec_return
> > -/**
> > - * arch_atomic64_dec_return - Atomic dec with full ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically decrement @v using full ordering.
> > - * Return new value.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic64_dec_return() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_dec_return(atomic64_t *v)
> >  {
> > @@ -2906,13 +2702,7 @@ arch_atomic64_fetch_dec_relaxed(atomic64_t *v)
> >  #else /* arch_atomic64_fetch_dec_relaxed */
> >  
> >  #ifndef arch_atomic64_fetch_dec_acquire
> > -/**
> > - * arch_atomic64_fetch_dec_acquire - Atomic dec with acquire ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically decrement @v using acquire ordering.
> > - * Return old value.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic64_fetch_dec_acquire() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_fetch_dec_acquire(atomic64_t *v)
> >  {
> > @@ -2924,13 +2714,7 @@ arch_atomic64_fetch_dec_acquire(atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_fetch_dec_release
> > -/**
> > - * arch_atomic64_fetch_dec_release - Atomic dec with release ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically decrement @v using release ordering.
> > - * Return old value.
> > - */
> > +// Fallback release omitting duplicate arch_atomic64_fetch_dec_release() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_fetch_dec_release(atomic64_t *v)
> >  {
> > @@ -2941,13 +2725,7 @@ arch_atomic64_fetch_dec_release(atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_fetch_dec
> > -/**
> > - * arch_atomic64_fetch_dec - Atomic dec with full ordering
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically decrement @v using full ordering.
> > - * Return old value.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic64_fetch_dec() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_fetch_dec(atomic64_t *v)
> >  {
> > @@ -3123,14 +2901,7 @@ arch_atomic64_fetch_andnot_relaxed(s64 i, atomic64_t *v)
> >  #else /* arch_atomic64_fetch_andnot_relaxed */
> >  
> >  #ifndef arch_atomic64_fetch_andnot_acquire
> > -/**
> > - * arch_atomic64_fetch_andnot_acquire - Atomic andnot with acquire ordering
> > - * @i: value to complement then AND
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically complement then AND @i with @v using acquire ordering.
> > - * Return old value.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic64_fetch_andnot_acquire() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
> >  {
> > @@ -3142,14 +2913,7 @@ arch_atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_fetch_andnot_release
> > -/**
> > - * arch_atomic64_fetch_andnot_release - Atomic andnot with release ordering
> > - * @i: value to complement then AND
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically complement then AND @i with @v using release ordering.
> > - * Return old value.
> > - */
> > +// Fallback release omitting duplicate arch_atomic64_fetch_andnot_release() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
> >  {
> > @@ -3160,14 +2924,7 @@ arch_atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_fetch_andnot
> > -/**
> > - * arch_atomic64_fetch_andnot - Atomic andnot with full ordering
> > - * @i: value to complement then AND
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically complement then AND @i with @v using full ordering.
> > - * Return old value.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic64_fetch_andnot() kernel-doc header.
> >  static __always_inline s64
> >  arch_atomic64_fetch_andnot(s64 i, atomic64_t *v)
> >  {
> > @@ -3560,18 +3317,7 @@ arch_atomic64_try_cmpxchg_relaxed(atomic64_t *v, s64 *old, s64 new)
> >  #else /* arch_atomic64_try_cmpxchg_relaxed */
> >  
> >  #ifndef arch_atomic64_try_cmpxchg_acquire
> > -/**
> > - * arch_atomic64_try_cmpxchg_acquire - Atomic try_cmpxchg with acquire ordering
> > - * @v: pointer of type atomic64_t
> > - * @old: desired old value to match
> > - * @new: new value to put in
> > - *
> > - * Atomically compares @new to *@v, and if equal,
> > - * stores @new to *@v, providing acquire ordering.
> > - * Returns @true if the cmpxchg operation succeeded,
> > - * and false otherwise.  Either way, stores the old
> > - * value of *@v to *@old.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic64_try_cmpxchg_acquire() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
> >  {
> > @@ -3583,18 +3329,7 @@ arch_atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
> >  #endif
> >  
> >  #ifndef arch_atomic64_try_cmpxchg_release
> > -/**
> > - * arch_atomic64_try_cmpxchg_release - Atomic try_cmpxchg with release ordering
> > - * @v: pointer of type atomic64_t
> > - * @old: desired old value to match
> > - * @new: new value to put in
> > - *
> > - * Atomically compares @new to *@v, and if equal,
> > - * stores @new to *@v, providing release ordering.
> > - * Returns @true if the cmpxchg operation succeeded,
> > - * and false otherwise.  Either way, stores the old
> > - * value of *@v to *@old.
> > - */
> > +// Fallback release omitting duplicate arch_atomic64_try_cmpxchg_release() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
> >  {
> > @@ -3605,18 +3340,7 @@ arch_atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
> >  #endif
> >  
> >  #ifndef arch_atomic64_try_cmpxchg
> > -/**
> > - * arch_atomic64_try_cmpxchg - Atomic try_cmpxchg with full ordering
> > - * @v: pointer of type atomic64_t
> > - * @old: desired old value to match
> > - * @new: new value to put in
> > - *
> > - * Atomically compares @new to *@v, and if equal,
> > - * stores @new to *@v, providing full ordering.
> > - * Returns @true if the cmpxchg operation succeeded,
> > - * and false otherwise.  Either way, stores the old
> > - * value of *@v to *@old.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic64_try_cmpxchg() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new)
> >  {
> > @@ -3761,15 +3485,7 @@ arch_atomic64_add_negative_relaxed(s64 i, atomic64_t *v)
> >  #else /* arch_atomic64_add_negative_relaxed */
> >  
> >  #ifndef arch_atomic64_add_negative_acquire
> > -/**
> > - * arch_atomic64_add_negative_acquire - Atomic add_negative with acquire ordering
> > - * @i: value to add
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically add @i with @v using acquire ordering.
> > - * Return @true if the result is negative, or @false when
> > - * the result is greater than or equal to zero.
> > - */
> > +// Fallback acquire omitting duplicate arch_atomic64_add_negative_acquire() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic64_add_negative_acquire(s64 i, atomic64_t *v)
> >  {
> > @@ -3781,15 +3497,7 @@ arch_atomic64_add_negative_acquire(s64 i, atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_add_negative_release
> > -/**
> > - * arch_atomic64_add_negative_release - Atomic add_negative with release ordering
> > - * @i: value to add
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically add @i with @v using release ordering.
> > - * Return @true if the result is negative, or @false when
> > - * the result is greater than or equal to zero.
> > - */
> > +// Fallback release omitting duplicate arch_atomic64_add_negative_release() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic64_add_negative_release(s64 i, atomic64_t *v)
> >  {
> > @@ -3800,15 +3508,7 @@ arch_atomic64_add_negative_release(s64 i, atomic64_t *v)
> >  #endif
> >  
> >  #ifndef arch_atomic64_add_negative
> > -/**
> > - * arch_atomic64_add_negative - Atomic add_negative with full ordering
> > - * @i: value to add
> > - * @v: pointer of type atomic64_t
> > - *
> > - * Atomically add @i with @v using full ordering.
> > - * Return @true if the result is negative, or @false when
> > - * the result is greater than or equal to zero.
> > - */
> > +// Fallback fence omitting duplicate arch_atomic64_add_negative() kernel-doc header.
> >  static __always_inline bool
> >  arch_atomic64_add_negative(s64 i, atomic64_t *v)
> >  {
> > @@ -3958,4 +3658,4 @@ arch_atomic64_dec_if_positive(atomic64_t *v)
> >  #endif
> >  
> >  #endif /* _LINUX_ATOMIC_FALLBACK_H */
> > -// 7c2c97cd48cf9c672efc44b9fed5a37b8970dde4
> > +// 9bf9febc5288ed9539d1b3cfbbc6e36743b74c3b
> > diff --git a/scripts/atomic/chkdup.sh b/scripts/atomic/chkdup.sh
> > new file mode 100644
> > index 000000000000..04bb4f5c5c34
> > --- /dev/null
> > +++ b/scripts/atomic/chkdup.sh
> > @@ -0,0 +1,27 @@
> > +#!/bin/sh
> > +# SPDX-License-Identifier: GPL-2.0
> > +#
> > +# Check to see if the specified atomic is already in use.  This is
> > +# done by keeping filenames in the temporary directory specified by the
> > +# environment variable T.
> > +#
> > +# Usage:
> > +#	chkdup.sh name fallback
> > +#
> > +# The "name" argument is the name of the function to be generated, and
> > +# the "fallback" argument is the name of the fallback script that is
> > +# doing the generation.
> > +#
> > +# If the function is a duplicate, output a comment saying so and
> > +# exit with non-zero (error) status.  Otherwise exit successfully
> > +#
> > +# If the function is a duplicate, output a comment saying so and
> > +# exit with non-zero (error) status.  Otherwise exit successfully.
> > +
> > +if test -f ${T}/${1}
> > +then
> > +	echo // Fallback ${2} omitting duplicate "${1}()" kernel-doc header.
> > +	exit 1
> > +fi
> > +touch ${T}/${1}
> > +exit 0
> > diff --git a/scripts/atomic/fallbacks/acquire b/scripts/atomic/fallbacks/acquire
> > index 08fc6c30a9ef..a349935ac7fe 100755
> > --- a/scripts/atomic/fallbacks/acquire
> > +++ b/scripts/atomic/fallbacks/acquire
> > @@ -1,5 +1,8 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}${name}${sfx}_acquire acquire
> > +then
> >  acqrel=acquire
> >  . ${ATOMICDIR}/acqrel.sh
> > +fi
> >  cat << EOF
> >  static __always_inline ${ret}
> >  arch_${atomic}_${pfx}${name}${sfx}_acquire(${params})
> > diff --git a/scripts/atomic/fallbacks/add_negative b/scripts/atomic/fallbacks/add_negative
> > index c032e8bec6e2..b105fdfe8fd1 100755
> > --- a/scripts/atomic/fallbacks/add_negative
> > +++ b/scripts/atomic/fallbacks/add_negative
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_add_negative${order} add_negative
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_add_negative${order} - Add and test if negative
> > @@ -7,6 +9,9 @@ cat <<EOF
> >   * Atomically adds @i to @v and returns @true if the result is negative,
> >   * or @false when the result is greater than or equal to zero.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline bool
> >  arch_${atomic}_add_negative${order}(${int} i, ${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/add_unless b/scripts/atomic/fallbacks/add_unless
> > index 650fee935aed..d72d382e3757 100755
> > --- a/scripts/atomic/fallbacks/add_unless
> > +++ b/scripts/atomic/fallbacks/add_unless
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_add_unless add_unless
> > +then
> >  cat << EOF
> >  /**
> >   * arch_${atomic}_add_unless - add unless the number is already a given value
> > @@ -8,6 +10,9 @@ cat << EOF
> >   * Atomically adds @a to @v, if @v was not already @u.
> >   * Returns @true if the addition was done.
> >   */
> > +EOF
> > +fi
> > +cat << EOF
> >  static __always_inline bool
> >  arch_${atomic}_add_unless(${atomic}_t *v, ${int} a, ${int} u)
> >  {
> > diff --git a/scripts/atomic/fallbacks/andnot b/scripts/atomic/fallbacks/andnot
> > index 9fbc0ce75a7c..57b2a187374a 100755
> > --- a/scripts/atomic/fallbacks/andnot
> > +++ b/scripts/atomic/fallbacks/andnot
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}andnot${sfx}${order} andnot
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_${pfx}andnot${sfx}${order} - Atomic and-not
> > @@ -7,6 +9,9 @@ cat <<EOF
> >   * Atomically and-not @i with @v using ${docbook_order} ordering.
> >   * returning ${docbook_oldnew} value.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline ${ret}
> >  arch_${atomic}_${pfx}andnot${sfx}${order}(${int} i, ${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/dec b/scripts/atomic/fallbacks/dec
> > index e99c8edd36a3..e44d3eb96d2b 100755
> > --- a/scripts/atomic/fallbacks/dec
> > +++ b/scripts/atomic/fallbacks/dec
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}dec${sfx}${order} dec
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_${pfx}dec${sfx}${order} - Atomic decrement
> > @@ -6,6 +8,9 @@ cat <<EOF
> >   * Atomically decrement @v with ${docbook_order} ordering,
> >   * returning ${docbook_oldnew} value.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline ${ret}
> >  arch_${atomic}_${pfx}dec${sfx}${order}(${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/dec_and_test b/scripts/atomic/fallbacks/dec_and_test
> > index 3720896b1afc..94f5a6d4827c 100755
> > --- a/scripts/atomic/fallbacks/dec_and_test
> > +++ b/scripts/atomic/fallbacks/dec_and_test
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_dec_and_test dec_and_test
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_dec_and_test - decrement and test
> > @@ -7,6 +9,9 @@ cat <<EOF
> >   * returns @true if the result is 0, or @false for all other
> >   * cases.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline bool
> >  arch_${atomic}_dec_and_test(${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/dec_if_positive b/scripts/atomic/fallbacks/dec_if_positive
> > index dedbdbc1487d..e27eb71dd1b2 100755
> > --- a/scripts/atomic/fallbacks/dec_if_positive
> > +++ b/scripts/atomic/fallbacks/dec_if_positive
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_dec_if_positive dec_if_positive
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_dec_if_positive - Atomic decrement if old value is positive
> > @@ -9,6 +11,9 @@ cat <<EOF
> >   * there @v will not be decremented, but -4 will be returned.  As a result,
> >   * if the return value is non-negative, then the value was in fact decremented.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline ${ret}
> >  arch_${atomic}_dec_if_positive(${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/dec_unless_positive b/scripts/atomic/fallbacks/dec_unless_positive
> > index c3d01d201c63..ee00fffc5f11 100755
> > --- a/scripts/atomic/fallbacks/dec_unless_positive
> > +++ b/scripts/atomic/fallbacks/dec_unless_positive
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_dec_unless_positive dec_unless_positive
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_dec_unless_positive - Atomic decrement if old value is non-positive
> > @@ -7,6 +9,9 @@ cat <<EOF
> >   * than or equal to zero.  Return @true if the decrement happened and
> >   * @false otherwise.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline bool
> >  arch_${atomic}_dec_unless_positive(${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/fence b/scripts/atomic/fallbacks/fence
> > index 975855dfba25..f4901343cd2b 100755
> > --- a/scripts/atomic/fallbacks/fence
> > +++ b/scripts/atomic/fallbacks/fence
> > @@ -1,5 +1,8 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}${name}${sfx} fence
> > +then
> >  acqrel=full
> >  . ${ATOMICDIR}/acqrel.sh
> > +fi
> >  cat <<EOF
> >  static __always_inline ${ret}
> >  arch_${atomic}_${pfx}${name}${sfx}(${params})
> > diff --git a/scripts/atomic/fallbacks/fetch_add_unless b/scripts/atomic/fallbacks/fetch_add_unless
> > index a1692df0d514..ec583d340785 100755
> > --- a/scripts/atomic/fallbacks/fetch_add_unless
> > +++ b/scripts/atomic/fallbacks/fetch_add_unless
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_fetch_add_unless fetch_add_unless
> > +then
> >  cat << EOF
> >  /**
> >   * arch_${atomic}_fetch_add_unless - add unless the number is already a given value
> > @@ -8,6 +10,9 @@ cat << EOF
> >   * Atomically adds @a to @v, so long as @v was not already @u.
> >   * Returns original value of @v.
> >   */
> > +EOF
> > +fi
> > +cat << EOF
> >  static __always_inline ${int}
> >  arch_${atomic}_fetch_add_unless(${atomic}_t *v, ${int} a, ${int} u)
> >  {
> > diff --git a/scripts/atomic/fallbacks/inc b/scripts/atomic/fallbacks/inc
> > index 3f2c0730cd0c..bb1d5ea6846c 100755
> > --- a/scripts/atomic/fallbacks/inc
> > +++ b/scripts/atomic/fallbacks/inc
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}inc${sfx}${order} inc
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_${pfx}inc${sfx}${order} - Atomic increment
> > @@ -6,6 +8,9 @@ cat <<EOF
> >   * Atomically increment @v with ${docbook_order} ordering,
> >   * returning ${docbook_oldnew} value.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline ${ret}
> >  arch_${atomic}_${pfx}inc${sfx}${order}(${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/inc_and_test b/scripts/atomic/fallbacks/inc_and_test
> > index cc3ac1dde508..dd74f6a5ca4a 100755
> > --- a/scripts/atomic/fallbacks/inc_and_test
> > +++ b/scripts/atomic/fallbacks/inc_and_test
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_inc_and_test inc_and_test
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_inc_and_test - increment and test
> > @@ -7,6 +9,9 @@ cat <<EOF
> >   * and returns @true if the result is zero, or @false for all
> >   * other cases.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline bool
> >  arch_${atomic}_inc_and_test(${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/inc_not_zero b/scripts/atomic/fallbacks/inc_not_zero
> > index 891fa3c057f6..38e2c13dab62 100755
> > --- a/scripts/atomic/fallbacks/inc_not_zero
> > +++ b/scripts/atomic/fallbacks/inc_not_zero
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_inc_not_zero inc_not_zero
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_inc_not_zero - increment unless the number is zero
> > @@ -6,6 +8,9 @@ cat <<EOF
> >   * Atomically increments @v by 1, if @v is non-zero.
> >   * Returns @true if the increment was done.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline bool
> >  arch_${atomic}_inc_not_zero(${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/inc_unless_negative b/scripts/atomic/fallbacks/inc_unless_negative
> > index 98830b0dcdb1..2dc853c4e5b9 100755
> > --- a/scripts/atomic/fallbacks/inc_unless_negative
> > +++ b/scripts/atomic/fallbacks/inc_unless_negative
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_inc_unless_negative inc_unless_negative
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_inc_unless_negative - Atomic increment if old value is non-negative
> > @@ -7,6 +9,9 @@ cat <<EOF
> >   * than or equal to zero.  Return @true if the increment happened and
> >   * @false otherwise.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline bool
> >  arch_${atomic}_inc_unless_negative(${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/read_acquire b/scripts/atomic/fallbacks/read_acquire
> > index 779f40c07018..680cd43080cb 100755
> > --- a/scripts/atomic/fallbacks/read_acquire
> > +++ b/scripts/atomic/fallbacks/read_acquire
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_read_acquire read_acquire
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_read_acquire - Atomic load acquire
> > @@ -6,6 +8,9 @@ cat <<EOF
> >   * Atomically load from *@v with acquire ordering, returning the value
> >   * loaded.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline ${ret}
> >  arch_${atomic}_read_acquire(const ${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/release b/scripts/atomic/fallbacks/release
> > index bce3a1cbd497..a1604df66ece 100755
> > --- a/scripts/atomic/fallbacks/release
> > +++ b/scripts/atomic/fallbacks/release
> > @@ -1,5 +1,8 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}${name}${sfx}_release release
> > +then
> >  acqrel=release
> >  . ${ATOMICDIR}/acqrel.sh
> > +fi
> >  cat <<EOF
> >  static __always_inline ${ret}
> >  arch_${atomic}_${pfx}${name}${sfx}_release(${params})
> > diff --git a/scripts/atomic/fallbacks/set_release b/scripts/atomic/fallbacks/set_release
> > index 46effb6203e5..2a65d3b29f4b 100755
> > --- a/scripts/atomic/fallbacks/set_release
> > +++ b/scripts/atomic/fallbacks/set_release
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_set_release set_release
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_set_release - Atomic store release
> > @@ -6,6 +8,9 @@ cat <<EOF
> >   *
> >   * Atomically store @i into *@v with release ordering.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline void
> >  arch_${atomic}_set_release(${atomic}_t *v, ${int} i)
> >  {
> > diff --git a/scripts/atomic/fallbacks/sub_and_test b/scripts/atomic/fallbacks/sub_and_test
> > index 204282e260ea..0397b0e92192 100755
> > --- a/scripts/atomic/fallbacks/sub_and_test
> > +++ b/scripts/atomic/fallbacks/sub_and_test
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_sub_and_test sub_and_test
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_sub_and_test - subtract value from variable and test result
> > @@ -8,6 +10,9 @@ cat <<EOF
> >   * @true if the result is zero, or @false for all
> >   * other cases.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline bool
> >  arch_${atomic}_sub_and_test(${int} i, ${atomic}_t *v)
> >  {
> > diff --git a/scripts/atomic/fallbacks/try_cmpxchg b/scripts/atomic/fallbacks/try_cmpxchg
> > index baf7412f9bf4..e08c5962dd83 100755
> > --- a/scripts/atomic/fallbacks/try_cmpxchg
> > +++ b/scripts/atomic/fallbacks/try_cmpxchg
> > @@ -1,3 +1,5 @@
> > +if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_try_cmpxchg${order} try_cmpxchg
> > +then
> >  cat <<EOF
> >  /**
> >   * arch_${atomic}_try_cmpxchg${order} - Atomic cmpxchg with bool return value
> > @@ -9,6 +11,9 @@ cat <<EOF
> >   * providing ${docbook_order} ordering.
> >   * Returns @true if the cmpxchg operation succeeded, and false otherwise.
> >   */
> > +EOF
> > +fi
> > +cat <<EOF
> >  static __always_inline bool
> >  arch_${atomic}_try_cmpxchg${order}(${atomic}_t *v, ${int} *old, ${int} new)
> >  {
> > diff --git a/scripts/atomic/gen-atomics.sh b/scripts/atomic/gen-atomics.sh
> > index 5b98a8307693..69bf3754df5a 100755
> > --- a/scripts/atomic/gen-atomics.sh
> > +++ b/scripts/atomic/gen-atomics.sh
> > @@ -3,6 +3,10 @@
> >  #
> >  # Generate atomic headers
> >  
> > +T="`mktemp -d ${TMPDIR-/tmp}/gen-atomics.sh.XXXXXX`"
> > +trap 'rm -rf $T' 0
> > +export T
> > +
> >  ATOMICDIR=$(dirname $0)
> >  ATOMICTBL=${ATOMICDIR}/atomics.tbl
> >  LINUXDIR=${ATOMICDIR}/../..
> > -- 
> > 2.40.1
> >
  
Peter Zijlstra May 11, 2023, 7:38 p.m. UTC | #3
On Thu, May 11, 2023 at 06:10:00PM +0100, Mark Rutland wrote:
> Hi Paul
> 
> On Wed, May 10, 2023 at 11:17:16AM -0700, Paul E. McKenney wrote:
> > The gen-atomics.sh script currently generates 42 duplicate definitions:
> > 
> > 	arch_atomic64_add_negative
> > 	arch_atomic64_add_negative_acquire
> > 	arch_atomic64_add_negative_release
> 
> 	[...]
> 
> > These duplicates are presumably to handle different architectures
> > generating hand-coded definitions for different subsets of the atomic
> > operations.
> 
> Yup, for each FULL/ACQUIRE/RELEASE/RELAXED variant of each op, we allow the
> archtiecture to choose between:
> 
> * Providing the ordering variant directly
> * Providing the FULL ordering variant only
> * Providing the RELAXED ordering variant only
> * Providing an equivalent op that we can build from
> 
> > However, generating duplicate kernel-doc headers is undesirable.
> 
> Understood -- I hadn't understood that duplication was a problem when this was
> originally written.
> 
> The way this is currently done is largely an artifact of our ifdeffery (and the
> kerneldoc for fallbacks living inthe fallback templates), and I think we can
> fix both of those.
> 
> > Therefore, generate only the first kernel-doc definition in a group
> > of duplicates.  A comment indicates the name of the function and the
> > fallback script that generated it.
> 
> I'm not keen on this approach, especially with the chkdup.sh script -- it feels
> like we're working around an underlying structural issue.
> 
> I think that we can restructure the ifdeffery so that each ordering variant
> gets its own ifdeffery, and then we could place the kerneldoc immediately above
> that, e.g.
> 
> 	/**
> 	 * arch_atomic_inc_return_release()
> 	 *
> 	 * [ full kerneldoc block here ]
> 	 */
> 	#if defined(arch_atomic_inc_return_release)
> 	/* defined in arch code */
> 	#elif defined(arch_atomic_inc_return_relaxed)
> 	[ define in terms of arch_atomic_inc_return_relaxed ]
> 	#elif defined(arch_atomic_inc_return)
> 	[ define in terms of arch_atomic_inc_return ]
> 	#else
> 	[ define in terms of arch_atomic_fetch_inc_release ]
> 	#endif
> 
> ... with similar for the mandatory ops that each arch must provide, e.g.
> 
> 	/**
> 	 * arch_atomic_or()
> 	 *
> 	 * [ full kerneldoc block here ]
> 	 */
> 	/* arch_atomic_or() is mandatory -- architectures must define it! */
> 
> I had a go at that restructuring today, and while local build testing indicates
> I haven't got it quite right, I think it's possible:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> 
> Does that sound ok to you?

If the end result is simpler scripts, sure.

I'm not at all keen to complicate the scripts for something daft like
kernel-doc. The last thing we need is documentation style weenies making
an unholy mess of things.
  
Paul E. McKenney May 11, 2023, 7:53 p.m. UTC | #4
On Thu, May 11, 2023 at 09:38:56PM +0200, Peter Zijlstra wrote:
> On Thu, May 11, 2023 at 06:10:00PM +0100, Mark Rutland wrote:
> > Hi Paul
> > 
> > On Wed, May 10, 2023 at 11:17:16AM -0700, Paul E. McKenney wrote:
> > > The gen-atomics.sh script currently generates 42 duplicate definitions:
> > > 
> > > 	arch_atomic64_add_negative
> > > 	arch_atomic64_add_negative_acquire
> > > 	arch_atomic64_add_negative_release
> > 
> > 	[...]
> > 
> > > These duplicates are presumably to handle different architectures
> > > generating hand-coded definitions for different subsets of the atomic
> > > operations.
> > 
> > Yup, for each FULL/ACQUIRE/RELEASE/RELAXED variant of each op, we allow the
> > archtiecture to choose between:
> > 
> > * Providing the ordering variant directly
> > * Providing the FULL ordering variant only
> > * Providing the RELAXED ordering variant only
> > * Providing an equivalent op that we can build from
> > 
> > > However, generating duplicate kernel-doc headers is undesirable.
> > 
> > Understood -- I hadn't understood that duplication was a problem when this was
> > originally written.
> > 
> > The way this is currently done is largely an artifact of our ifdeffery (and the
> > kerneldoc for fallbacks living inthe fallback templates), and I think we can
> > fix both of those.
> > 
> > > Therefore, generate only the first kernel-doc definition in a group
> > > of duplicates.  A comment indicates the name of the function and the
> > > fallback script that generated it.
> > 
> > I'm not keen on this approach, especially with the chkdup.sh script -- it feels
> > like we're working around an underlying structural issue.
> > 
> > I think that we can restructure the ifdeffery so that each ordering variant
> > gets its own ifdeffery, and then we could place the kerneldoc immediately above
> > that, e.g.
> > 
> > 	/**
> > 	 * arch_atomic_inc_return_release()
> > 	 *
> > 	 * [ full kerneldoc block here ]
> > 	 */
> > 	#if defined(arch_atomic_inc_return_release)
> > 	/* defined in arch code */
> > 	#elif defined(arch_atomic_inc_return_relaxed)
> > 	[ define in terms of arch_atomic_inc_return_relaxed ]
> > 	#elif defined(arch_atomic_inc_return)
> > 	[ define in terms of arch_atomic_inc_return ]
> > 	#else
> > 	[ define in terms of arch_atomic_fetch_inc_release ]
> > 	#endif
> > 
> > ... with similar for the mandatory ops that each arch must provide, e.g.
> > 
> > 	/**
> > 	 * arch_atomic_or()
> > 	 *
> > 	 * [ full kerneldoc block here ]
> > 	 */
> > 	/* arch_atomic_or() is mandatory -- architectures must define it! */
> > 
> > I had a go at that restructuring today, and while local build testing indicates
> > I haven't got it quite right, I think it's possible:
> > 
> >   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> > 
> > Does that sound ok to you?
> 
> If the end result is simpler scripts, sure.
> 
> I'm not at all keen to complicate the scripts for something daft like
> kernel-doc. The last thing we need is documentation style weenies making
> an unholy mess of things.

Do you have an alternative suggestion for generating the kernel-doc?
The current lack of it is problematic.

							Thanx, Paul
  
Peter Zijlstra May 11, 2023, 8:01 p.m. UTC | #5
On Thu, May 11, 2023 at 12:53:46PM -0700, Paul E. McKenney wrote:
> Do you have an alternative suggestion for generating the kernel-doc?
> The current lack of it is problematic.

I've never found a lack of kernel-doc to be a problem. And I'm very much
against complicating the scripts to add it.

Also, there's Documentation/atomic_t.txt
  
Peter Zijlstra May 11, 2023, 8:18 p.m. UTC | #6
On Wed, May 10, 2023 at 11:17:16AM -0700, Paul E. McKenney wrote:
> The gen-atomics.sh script currently generates 42 duplicate definitions:
> 
> 	arch_atomic64_add_negative
> 	arch_atomic64_add_negative_acquire
> 	arch_atomic64_add_negative_release
> 	arch_atomic64_dec_return
> 	arch_atomic64_dec_return_acquire
> 	arch_atomic64_dec_return_release
> 	arch_atomic64_fetch_andnot
> 	arch_atomic64_fetch_andnot_acquire
> 	arch_atomic64_fetch_andnot_release
> 	arch_atomic64_fetch_dec
> 	arch_atomic64_fetch_dec_acquire
> 	arch_atomic64_fetch_dec_release
> 	arch_atomic64_fetch_inc
> 	arch_atomic64_fetch_inc_acquire
> 	arch_atomic64_fetch_inc_release
> 	arch_atomic64_inc_return
> 	arch_atomic64_inc_return_acquire
> 	arch_atomic64_inc_return_release
> 	arch_atomic64_try_cmpxchg
> 	arch_atomic64_try_cmpxchg_acquire
> 	arch_atomic64_try_cmpxchg_release
> 	arch_atomic_add_negative
> 	arch_atomic_add_negative_acquire
> 	arch_atomic_add_negative_release
> 	arch_atomic_dec_return
> 	arch_atomic_dec_return_acquire
> 	arch_atomic_dec_return_release
> 	arch_atomic_fetch_andnot
> 	arch_atomic_fetch_andnot_acquire
> 	arch_atomic_fetch_andnot_release
> 	arch_atomic_fetch_dec
> 	arch_atomic_fetch_dec_acquire
> 	arch_atomic_fetch_dec_release
> 	arch_atomic_fetch_inc
> 	arch_atomic_fetch_inc_acquire
> 	arch_atomic_fetch_inc_release
> 	arch_atomic_inc_return
> 	arch_atomic_inc_return_acquire
> 	arch_atomic_inc_return_release
> 	arch_atomic_try_cmpxchg
> 	arch_atomic_try_cmpxchg_acquire
> 	arch_atomic_try_cmpxchg_release
> 
> These duplicates are presumably to handle different architectures
> generating hand-coded definitions for different subsets of the atomic
> operations.  However, generating duplicate kernel-doc headers is
> undesirable.
> 
> Therefore, generate only the first kernel-doc definition in a group
> of duplicates.  A comment indicates the name of the function and the
> fallback script that generated it.

So my canonical solution to fixing kernel-doc related problems is this
trivial regex:

	s/\/\*\*/\/\*/

works every time.

And is *much* simpler than this:

>  scripts/atomic/chkdup.sh                     |  27 ++
>  scripts/atomic/fallbacks/acquire             |   3 +
>  scripts/atomic/fallbacks/add_negative        |   5 +
>  scripts/atomic/fallbacks/add_unless          |   5 +
>  scripts/atomic/fallbacks/andnot              |   5 +
>  scripts/atomic/fallbacks/dec                 |   5 +
>  scripts/atomic/fallbacks/dec_and_test        |   5 +
>  scripts/atomic/fallbacks/dec_if_positive     |   5 +
>  scripts/atomic/fallbacks/dec_unless_positive |   5 +
>  scripts/atomic/fallbacks/fence               |   3 +
>  scripts/atomic/fallbacks/fetch_add_unless    |   5 +
>  scripts/atomic/fallbacks/inc                 |   5 +
>  scripts/atomic/fallbacks/inc_and_test        |   5 +
>  scripts/atomic/fallbacks/inc_not_zero        |   5 +
>  scripts/atomic/fallbacks/inc_unless_negative |   5 +
>  scripts/atomic/fallbacks/read_acquire        |   5 +
>  scripts/atomic/fallbacks/release             |   3 +
>  scripts/atomic/fallbacks/set_release         |   5 +
>  scripts/atomic/fallbacks/sub_and_test        |   5 +
>  scripts/atomic/fallbacks/try_cmpxchg         |   5 +
>  scripts/atomic/gen-atomics.sh                |   4 +
  
Paul E. McKenney May 11, 2023, 8:25 p.m. UTC | #7
On Thu, May 11, 2023 at 10:01:42PM +0200, Peter Zijlstra wrote:
> On Thu, May 11, 2023 at 12:53:46PM -0700, Paul E. McKenney wrote:
> > Do you have an alternative suggestion for generating the kernel-doc?
> > The current lack of it is problematic.
> 
> I've never found a lack of kernel-doc to be a problem. And I'm very much
> against complicating the scripts to add it.

I am sure that you have not recently found the lack of kernel-doc for
the atomic operations to be a problem, given that you wrote many of
these functions.

OK, you mentioned concerns about documentation people nitpicking.  This
can be dealt with.  The added scripting is not that large or complex.

> Also, there's Documentation/atomic_t.txt

Yes, if you very carefully read that document end to end, correctly
interpreting it all, you will know what you need to.  Of course, first
you have to find it.  And then you must avoid any lapses while reading
it while under pressure.  Not particularly friendly to someone trying
to chase a bug.

							Thanx, Paul
  
Paul E. McKenney May 11, 2023, 8:29 p.m. UTC | #8
On Thu, May 11, 2023 at 10:18:37PM +0200, Peter Zijlstra wrote:
> On Wed, May 10, 2023 at 11:17:16AM -0700, Paul E. McKenney wrote:
> > The gen-atomics.sh script currently generates 42 duplicate definitions:
> > 
> > 	arch_atomic64_add_negative
> > 	arch_atomic64_add_negative_acquire
> > 	arch_atomic64_add_negative_release
> > 	arch_atomic64_dec_return
> > 	arch_atomic64_dec_return_acquire
> > 	arch_atomic64_dec_return_release
> > 	arch_atomic64_fetch_andnot
> > 	arch_atomic64_fetch_andnot_acquire
> > 	arch_atomic64_fetch_andnot_release
> > 	arch_atomic64_fetch_dec
> > 	arch_atomic64_fetch_dec_acquire
> > 	arch_atomic64_fetch_dec_release
> > 	arch_atomic64_fetch_inc
> > 	arch_atomic64_fetch_inc_acquire
> > 	arch_atomic64_fetch_inc_release
> > 	arch_atomic64_inc_return
> > 	arch_atomic64_inc_return_acquire
> > 	arch_atomic64_inc_return_release
> > 	arch_atomic64_try_cmpxchg
> > 	arch_atomic64_try_cmpxchg_acquire
> > 	arch_atomic64_try_cmpxchg_release
> > 	arch_atomic_add_negative
> > 	arch_atomic_add_negative_acquire
> > 	arch_atomic_add_negative_release
> > 	arch_atomic_dec_return
> > 	arch_atomic_dec_return_acquire
> > 	arch_atomic_dec_return_release
> > 	arch_atomic_fetch_andnot
> > 	arch_atomic_fetch_andnot_acquire
> > 	arch_atomic_fetch_andnot_release
> > 	arch_atomic_fetch_dec
> > 	arch_atomic_fetch_dec_acquire
> > 	arch_atomic_fetch_dec_release
> > 	arch_atomic_fetch_inc
> > 	arch_atomic_fetch_inc_acquire
> > 	arch_atomic_fetch_inc_release
> > 	arch_atomic_inc_return
> > 	arch_atomic_inc_return_acquire
> > 	arch_atomic_inc_return_release
> > 	arch_atomic_try_cmpxchg
> > 	arch_atomic_try_cmpxchg_acquire
> > 	arch_atomic_try_cmpxchg_release
> > 
> > These duplicates are presumably to handle different architectures
> > generating hand-coded definitions for different subsets of the atomic
> > operations.  However, generating duplicate kernel-doc headers is
> > undesirable.
> > 
> > Therefore, generate only the first kernel-doc definition in a group
> > of duplicates.  A comment indicates the name of the function and the
> > fallback script that generated it.
> 
> So my canonical solution to fixing kernel-doc related problems is this
> trivial regex:
> 
> 	s/\/\*\*/\/\*/
> 
> works every time.

Can't say that I am a fan of that approach.

> And is *much* simpler than this:
> 
> >  scripts/atomic/chkdup.sh                     |  27 ++
> >  scripts/atomic/fallbacks/acquire             |   3 +
> >  scripts/atomic/fallbacks/add_negative        |   5 +
> >  scripts/atomic/fallbacks/add_unless          |   5 +
> >  scripts/atomic/fallbacks/andnot              |   5 +
> >  scripts/atomic/fallbacks/dec                 |   5 +
> >  scripts/atomic/fallbacks/dec_and_test        |   5 +
> >  scripts/atomic/fallbacks/dec_if_positive     |   5 +
> >  scripts/atomic/fallbacks/dec_unless_positive |   5 +
> >  scripts/atomic/fallbacks/fence               |   3 +
> >  scripts/atomic/fallbacks/fetch_add_unless    |   5 +
> >  scripts/atomic/fallbacks/inc                 |   5 +
> >  scripts/atomic/fallbacks/inc_and_test        |   5 +
> >  scripts/atomic/fallbacks/inc_not_zero        |   5 +
> >  scripts/atomic/fallbacks/inc_unless_negative |   5 +
> >  scripts/atomic/fallbacks/read_acquire        |   5 +
> >  scripts/atomic/fallbacks/release             |   3 +
> >  scripts/atomic/fallbacks/set_release         |   5 +
> >  scripts/atomic/fallbacks/sub_and_test        |   5 +
> >  scripts/atomic/fallbacks/try_cmpxchg         |   5 +
> >  scripts/atomic/gen-atomics.sh                |   4 +

This is not a huge addition, now is it?

							Thanx, Paul
  
Peter Zijlstra May 11, 2023, 8:46 p.m. UTC | #9
On Thu, May 11, 2023 at 01:25:18PM -0700, Paul E. McKenney wrote:
> On Thu, May 11, 2023 at 10:01:42PM +0200, Peter Zijlstra wrote:
> > On Thu, May 11, 2023 at 12:53:46PM -0700, Paul E. McKenney wrote:
> > > Do you have an alternative suggestion for generating the kernel-doc?
> > > The current lack of it is problematic.
> > 
> > I've never found a lack of kernel-doc to be a problem. And I'm very much
> > against complicating the scripts to add it.
> 
> I am sure that you have not recently found the lack of kernel-doc for
> the atomic operations to be a problem, given that you wrote many of
> these functions.

Sure; but I meant in general -- I've *never* used kernel-doc. Comments I
occasionally read, and sometimes they're not even broken either, but
kernel-doc, nope.

> OK, you mentioned concerns about documentation people nitpicking.  This
> can be dealt with.  The added scripting is not that large or complex.
> 
> > Also, there's Documentation/atomic_t.txt
> 
> Yes, if you very carefully read that document end to end, correctly
> interpreting it all, you will know what you need to.  Of course, first
> you have to find it.  And then you must avoid any lapses while reading
> it while under pressure.  Not particularly friendly to someone trying
> to chase a bug.

It's either brief and terse or tediously long -- I vastly prefer the
former, my brain can much better parse structure than English prose.

Also, I find, pressure is never conductive to anything, except prehaps
cooking rice and steam trains (because nothing is as delicous as a
pressure cooked train -- oh wait).

Add enough pressure and the human brain reduces to driven and can't read
even the most coherent of text no matter how easy to find.

In such situations it's for the manager to take the pressure away and
the engineer to think in relative peace.
  
Peter Zijlstra May 11, 2023, 8:48 p.m. UTC | #10
On Thu, May 11, 2023 at 10:46:33PM +0200, Peter Zijlstra wrote:
> On Thu, May 11, 2023 at 01:25:18PM -0700, Paul E. McKenney wrote:
> > On Thu, May 11, 2023 at 10:01:42PM +0200, Peter Zijlstra wrote:
> > > On Thu, May 11, 2023 at 12:53:46PM -0700, Paul E. McKenney wrote:
> > > > Do you have an alternative suggestion for generating the kernel-doc?
> > > > The current lack of it is problematic.
> > > 
> > > I've never found a lack of kernel-doc to be a problem. And I'm very much
> > > against complicating the scripts to add it.
> > 
> > I am sure that you have not recently found the lack of kernel-doc for
> > the atomic operations to be a problem, given that you wrote many of
> > these functions.
> 
> Sure; but I meant in general -- I've *never* used kernel-doc. Comments I
> occasionally read, and sometimes they're not even broken either, but
> kernel-doc, nope.
> 
> > OK, you mentioned concerns about documentation people nitpicking.  This
> > can be dealt with.  The added scripting is not that large or complex.
> > 
> > > Also, there's Documentation/atomic_t.txt
> > 
> > Yes, if you very carefully read that document end to end, correctly
> > interpreting it all, you will know what you need to.  Of course, first
> > you have to find it.  And then you must avoid any lapses while reading
> > it while under pressure.  Not particularly friendly to someone trying
> > to chase a bug.
> 
> It's either brief and terse or tediously long -- I vastly prefer the
> former, my brain can much better parse structure than English prose.
> 
> Also, I find, pressure is never conductive to anything, except prehaps
> cooking rice and steam trains (because nothing is as delicous as a
> pressure cooked train -- oh wait).
> 
> Add enough pressure and the human brain reduces to driven and can't read

Just in case it weren't clear: s/driven/drivel/

> even the most coherent of text no matter how easy to find.
> 
> In such situations it's for the manager to take the pressure away and
> the engineer to think in relative peace.
  
Paul E. McKenney May 11, 2023, 9:24 p.m. UTC | #11
On Thu, May 11, 2023 at 10:48:06PM +0200, Peter Zijlstra wrote:
> On Thu, May 11, 2023 at 10:46:33PM +0200, Peter Zijlstra wrote:
> > On Thu, May 11, 2023 at 01:25:18PM -0700, Paul E. McKenney wrote:
> > > On Thu, May 11, 2023 at 10:01:42PM +0200, Peter Zijlstra wrote:
> > > > On Thu, May 11, 2023 at 12:53:46PM -0700, Paul E. McKenney wrote:
> > > > > Do you have an alternative suggestion for generating the kernel-doc?
> > > > > The current lack of it is problematic.
> > > > 
> > > > I've never found a lack of kernel-doc to be a problem. And I'm very much
> > > > against complicating the scripts to add it.
> > > 
> > > I am sure that you have not recently found the lack of kernel-doc for
> > > the atomic operations to be a problem, given that you wrote many of
> > > these functions.
> > 
> > Sure; but I meant in general -- I've *never* used kernel-doc. Comments I
> > occasionally read, and sometimes they're not even broken either, but
> > kernel-doc, nope.

I am not arguing that *you* need kernel-doc, and I must admit that I
also tend to look much more carefully at the code than the comments.
But not everyone has your level of code-reading talent, nor does everyone
have my half century of practice reading code.

(OK, OK, so it won't really be a half century until this coming
September!)

> > > OK, you mentioned concerns about documentation people nitpicking.  This
> > > can be dealt with.  The added scripting is not that large or complex.
> > > 
> > > > Also, there's Documentation/atomic_t.txt
> > > 
> > > Yes, if you very carefully read that document end to end, correctly
> > > interpreting it all, you will know what you need to.  Of course, first
> > > you have to find it.  And then you must avoid any lapses while reading
> > > it while under pressure.  Not particularly friendly to someone trying
> > > to chase a bug.
> > 
> > It's either brief and terse or tediously long -- I vastly prefer the
> > former, my brain can much better parse structure than English prose.

Agreed, English prose does have its challenges, no two ways about it.

But in order to successfully communicate with someone, it is necessary
to start where that person is, not where we might prefer them to be.
And there are quite a few people who benefit from a bit of English prose.

As long as we are picking on languages, there are some who assert that
Dutch is the easiest language for native English speakers to learn.
I know nothing myself, but for the purposes of this discussion, I will
assume that this is because Dutch uses similar words but is better
structured than is English.  As opposed, say, that Dutch is messed up
almost exactly the same ways that English is.  ;-)

> > Also, I find, pressure is never conductive to anything, except prehaps
> > cooking rice and steam trains (because nothing is as delicous as a
> > pressure cooked train -- oh wait).
> > 
> > Add enough pressure and the human brain reduces to driven and can't read
> 
> Just in case it weren't clear: s/driven/drivel/

You know, my brain auto-corrected and I didn't even notice.  And I still
sometimes wonder why I fail to spot bugs.  ;-)

> > even the most coherent of text no matter how easy to find.
> > 
> > In such situations it's for the manager to take the pressure away and
> > the engineer to think in relative peace.

I won't argue, having forced that a few times back in past lives.
"No, you don't have to get this done by Friday, and if anyone tells
you differently, you tell them to talk to me."  In one memorable case,
once pressure was relieved, they actually got it done before Friday.

Still, that is no reason to make that poor engineer's life even harder.
After all, there never have been more than a handful of managers that
I had that kind of influence over.  Plus there is the occasional true
emergency, though admittedly far fewer true emergencies that proclaimed
emergencies.

But suppose your response to someone nitpicking the atomic-operation
kernel-doc could simply be "Not my problem, go talk to Paul."  I would
of course be plenty happy to respond appropriately to people who expect
to read a long series of kernel-doc entries for atomic operations as
if it was a novel.  For some appropriate definition of "appropriately",
of course.

Would that help?

							Thanx, Paul
  
Mark Rutland May 12, 2023, 1:18 p.m. UTC | #12
On Thu, May 11, 2023 at 12:12:16PM -0700, Paul E. McKenney wrote:
> On Thu, May 11, 2023 at 06:10:00PM +0100, Mark Rutland wrote:
> > I think that we can restructure the ifdeffery so that each ordering variant
> > gets its own ifdeffery, and then we could place the kerneldoc immediately above
> > that, e.g.
> > 
> > 	/**
> > 	 * arch_atomic_inc_return_release()
> > 	 *
> > 	 * [ full kerneldoc block here ]
> > 	 */
> > 	#if defined(arch_atomic_inc_return_release)
> > 	/* defined in arch code */
> > 	#elif defined(arch_atomic_inc_return_relaxed)
> > 	[ define in terms of arch_atomic_inc_return_relaxed ]
> > 	#elif defined(arch_atomic_inc_return)
> > 	[ define in terms of arch_atomic_inc_return ]
> > 	#else
> > 	[ define in terms of arch_atomic_fetch_inc_release ]
> > 	#endif
> > 
> > ... with similar for the mandatory ops that each arch must provide, e.g.
> > 
> > 	/**
> > 	 * arch_atomic_or()
> > 	 *
> > 	 * [ full kerneldoc block here ]
> > 	 */
> > 	/* arch_atomic_or() is mandatory -- architectures must define it! */
> > 
> > I had a go at that restructuring today, and while local build testing indicates
> > I haven't got it quite right, I think it's possible:
> > 
> >   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> > 
> > Does that sound ok to you?
> 
> At first glance, it appears that your "TODO" locations have the same
> information that I was using, so it should not be hard for me to adapt the
> current kernel-doc generation to your new scheme.  (Famous last words!)

Great!

> Plus having the kernel-doc generation all in one place does have some
> serious attractions.

:)

> I will continue maintaining my current stack, but would of course be
> happy to port it on top of your refactoring.  If it turns out that
> the refactoring will take a long time, we can discuss what to do in
> the meantime.  But here is hoping that the refactoring goes smoothly!
> That would be easier all around.  ;-)

FWIW, I think that's working now; every cross-build I've tried works.

I've updated the branch at:

  https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework

Tagged as:

  atomics-fallback-rework-20230512

Thanks,
Mark.
  
Mark Rutland May 12, 2023, 1:30 p.m. UTC | #13
On Thu, May 11, 2023 at 09:38:56PM +0200, Peter Zijlstra wrote:
> On Thu, May 11, 2023 at 06:10:00PM +0100, Mark Rutland wrote:
> > Hi Paul
> > 
> > On Wed, May 10, 2023 at 11:17:16AM -0700, Paul E. McKenney wrote:
> > > The gen-atomics.sh script currently generates 42 duplicate definitions:
> > > 
> > > 	arch_atomic64_add_negative
> > > 	arch_atomic64_add_negative_acquire
> > > 	arch_atomic64_add_negative_release
> > 
> > 	[...]
> > 
> > > These duplicates are presumably to handle different architectures
> > > generating hand-coded definitions for different subsets of the atomic
> > > operations.
> > 
> > Yup, for each FULL/ACQUIRE/RELEASE/RELAXED variant of each op, we allow the
> > archtiecture to choose between:
> > 
> > * Providing the ordering variant directly
> > * Providing the FULL ordering variant only
> > * Providing the RELAXED ordering variant only
> > * Providing an equivalent op that we can build from
> > 
> > > However, generating duplicate kernel-doc headers is undesirable.
> > 
> > Understood -- I hadn't understood that duplication was a problem when this was
> > originally written.
> > 
> > The way this is currently done is largely an artifact of our ifdeffery (and the
> > kerneldoc for fallbacks living inthe fallback templates), and I think we can
> > fix both of those.
> > 
> > > Therefore, generate only the first kernel-doc definition in a group
> > > of duplicates.  A comment indicates the name of the function and the
> > > fallback script that generated it.
> > 
> > I'm not keen on this approach, especially with the chkdup.sh script -- it feels
> > like we're working around an underlying structural issue.
> > 
> > I think that we can restructure the ifdeffery so that each ordering variant
> > gets its own ifdeffery, and then we could place the kerneldoc immediately above
> > that, e.g.
> > 
> > 	/**
> > 	 * arch_atomic_inc_return_release()
> > 	 *
> > 	 * [ full kerneldoc block here ]
> > 	 */
> > 	#if defined(arch_atomic_inc_return_release)
> > 	/* defined in arch code */
> > 	#elif defined(arch_atomic_inc_return_relaxed)
> > 	[ define in terms of arch_atomic_inc_return_relaxed ]
> > 	#elif defined(arch_atomic_inc_return)
> > 	[ define in terms of arch_atomic_inc_return ]
> > 	#else
> > 	[ define in terms of arch_atomic_fetch_inc_release ]
> > 	#endif
> > 
> > ... with similar for the mandatory ops that each arch must provide, e.g.
> > 
> > 	/**
> > 	 * arch_atomic_or()
> > 	 *
> > 	 * [ full kerneldoc block here ]
> > 	 */
> > 	/* arch_atomic_or() is mandatory -- architectures must define it! */
> > 
> > I had a go at that restructuring today, and while local build testing indicates
> > I haven't got it quite right, I think it's possible:
> > 
> >   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> > 
> > Does that sound ok to you?
> 
> If the end result is simpler scripts, sure.

FWIW, regardless of the comments, I'd like to make this restructuring as it
makes it easier to add some more fallback cases, and I find the generated
ifdeffery a bit easier to follow when it's a chain of of-elif-elif-else-end
rather than a few nested cases.

> I'm not at all keen to complicate the scripts for something daft like
> kernel-doc. The last thing we need is documentation style weenies making
> an unholy mess of things.

Sure. I agree we don't want to bend over backwards for it at the cost of
maintainability, but I think it can be made pretty simple and self-contained,
and hopefully we can prove that with a v2 or v3. ;)

If nothing else, handling this centrally means that we'll have *one* set of
comments for this rather than a tonne of randomly managed copies in arch
code, which seems like a win...

Thanks,
Mark.
  
Paul E. McKenney May 12, 2023, 4:01 p.m. UTC | #14
On Fri, May 12, 2023 at 02:18:48PM +0100, Mark Rutland wrote:
> On Thu, May 11, 2023 at 12:12:16PM -0700, Paul E. McKenney wrote:
> > On Thu, May 11, 2023 at 06:10:00PM +0100, Mark Rutland wrote:
> > > I think that we can restructure the ifdeffery so that each ordering variant
> > > gets its own ifdeffery, and then we could place the kerneldoc immediately above
> > > that, e.g.
> > > 
> > > 	/**
> > > 	 * arch_atomic_inc_return_release()
> > > 	 *
> > > 	 * [ full kerneldoc block here ]
> > > 	 */
> > > 	#if defined(arch_atomic_inc_return_release)
> > > 	/* defined in arch code */
> > > 	#elif defined(arch_atomic_inc_return_relaxed)
> > > 	[ define in terms of arch_atomic_inc_return_relaxed ]
> > > 	#elif defined(arch_atomic_inc_return)
> > > 	[ define in terms of arch_atomic_inc_return ]
> > > 	#else
> > > 	[ define in terms of arch_atomic_fetch_inc_release ]
> > > 	#endif
> > > 
> > > ... with similar for the mandatory ops that each arch must provide, e.g.
> > > 
> > > 	/**
> > > 	 * arch_atomic_or()
> > > 	 *
> > > 	 * [ full kerneldoc block here ]
> > > 	 */
> > > 	/* arch_atomic_or() is mandatory -- architectures must define it! */
> > > 
> > > I had a go at that restructuring today, and while local build testing indicates
> > > I haven't got it quite right, I think it's possible:
> > > 
> > >   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> > > 
> > > Does that sound ok to you?
> > 
> > At first glance, it appears that your "TODO" locations have the same
> > information that I was using, so it should not be hard for me to adapt the
> > current kernel-doc generation to your new scheme.  (Famous last words!)
> 
> Great!
> 
> > Plus having the kernel-doc generation all in one place does have some
> > serious attractions.
> 
> :)
> 
> > I will continue maintaining my current stack, but would of course be
> > happy to port it on top of your refactoring.  If it turns out that
> > the refactoring will take a long time, we can discuss what to do in
> > the meantime.  But here is hoping that the refactoring goes smoothly!
> > That would be easier all around.  ;-)
> 
> FWIW, I think that's working now; every cross-build I've tried works.
> 
> I've updated the branch at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> 
> Tagged as:
> 
>   atomics-fallback-rework-20230512

Thank you very much!

I expect to send v2 of my original late today on the perhaps unlikely
off-chance that someone might be interested in reviewing the verbiage.

More to the point, I have started porting my changes on top of your
stack.  My thought is to have a separate "."-included script that does
the kernel-doc work.

I am also thinking in terms of putting the kernel-doc generation into
an "else" clause to the "is mandatory" check, and leaving the kernel-doc
for the mandatory functions in arch/x86/include/asm/atomic.h.

But in both cases, please let me know if something else would work better.

							Thanx, Paul
  
Mark Rutland May 12, 2023, 5:03 p.m. UTC | #15
On Fri, May 12, 2023 at 09:01:27AM -0700, Paul E. McKenney wrote:
> On Fri, May 12, 2023 at 02:18:48PM +0100, Mark Rutland wrote:
> > On Thu, May 11, 2023 at 12:12:16PM -0700, Paul E. McKenney wrote:
> > > On Thu, May 11, 2023 at 06:10:00PM +0100, Mark Rutland wrote:
> > > > I think that we can restructure the ifdeffery so that each ordering variant
> > > > gets its own ifdeffery, and then we could place the kerneldoc immediately above
> > > > that, e.g.
> > > > 
> > > > 	/**
> > > > 	 * arch_atomic_inc_return_release()
> > > > 	 *
> > > > 	 * [ full kerneldoc block here ]
> > > > 	 */
> > > > 	#if defined(arch_atomic_inc_return_release)
> > > > 	/* defined in arch code */
> > > > 	#elif defined(arch_atomic_inc_return_relaxed)
> > > > 	[ define in terms of arch_atomic_inc_return_relaxed ]
> > > > 	#elif defined(arch_atomic_inc_return)
> > > > 	[ define in terms of arch_atomic_inc_return ]
> > > > 	#else
> > > > 	[ define in terms of arch_atomic_fetch_inc_release ]
> > > > 	#endif
> > > > 
> > > > ... with similar for the mandatory ops that each arch must provide, e.g.
> > > > 
> > > > 	/**
> > > > 	 * arch_atomic_or()
> > > > 	 *
> > > > 	 * [ full kerneldoc block here ]
> > > > 	 */
> > > > 	/* arch_atomic_or() is mandatory -- architectures must define it! */
> > > > 
> > > > I had a go at that restructuring today, and while local build testing indicates
> > > > I haven't got it quite right, I think it's possible:
> > > > 
> > > >   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> > > > 
> > > > Does that sound ok to you?
> > > 
> > > At first glance, it appears that your "TODO" locations have the same
> > > information that I was using, so it should not be hard for me to adapt the
> > > current kernel-doc generation to your new scheme.  (Famous last words!)
> > 
> > Great!
> > 
> > > Plus having the kernel-doc generation all in one place does have some
> > > serious attractions.
> > 
> > :)
> > 
> > > I will continue maintaining my current stack, but would of course be
> > > happy to port it on top of your refactoring.  If it turns out that
> > > the refactoring will take a long time, we can discuss what to do in
> > > the meantime.  But here is hoping that the refactoring goes smoothly!
> > > That would be easier all around.  ;-)
> > 
> > FWIW, I think that's working now; every cross-build I've tried works.
> > 
> > I've updated the branch at:
> > 
> >   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> > 
> > Tagged as:
> > 
> >   atomics-fallback-rework-20230512
> 
> Thank you very much!
> 
> I expect to send v2 of my original late today on the perhaps unlikely
> off-chance that someone might be interested in reviewing the verbiage.

I'll be more than happy to, though I suspect "late today" is far too late today
for me in UK time terms, so I probably won't look until Monday.

> More to the point, I have started porting my changes on top of your
> stack.  My thought is to have a separate "."-included script that does
> the kernel-doc work.

I was thinking that we'd have a gen_kerneldoc(...) shell function (probably in
atomic-tbl.sh), but that's an easy thing to refactor after v2, so either way is
fine for now!

> I am also thinking in terms of putting the kernel-doc generation into
> an "else" clause to the "is mandatory" check, and leaving the kernel-doc
> for the mandatory functions in arch/x86/include/asm/atomic.h.

My thinking was that all the kernel-doc bits should live in the common header
so that they're all easy to find when looking at the source code, and since if
feels a bit weird to have to look into arch/x86/ to figure out the semantics of
a function on !x86.

That said, if that's painful for some reason, please go with the easiest option
for now and we can figure out how to attack it for v3. :)

Thanks,
Mark.
  
Paul E. McKenney May 12, 2023, 6:42 p.m. UTC | #16
On Fri, May 12, 2023 at 06:03:26PM +0100, Mark Rutland wrote:
> On Fri, May 12, 2023 at 09:01:27AM -0700, Paul E. McKenney wrote:
> > On Fri, May 12, 2023 at 02:18:48PM +0100, Mark Rutland wrote:
> > > On Thu, May 11, 2023 at 12:12:16PM -0700, Paul E. McKenney wrote:
> > > > On Thu, May 11, 2023 at 06:10:00PM +0100, Mark Rutland wrote:
> > > > > I think that we can restructure the ifdeffery so that each ordering variant
> > > > > gets its own ifdeffery, and then we could place the kerneldoc immediately above
> > > > > that, e.g.
> > > > > 
> > > > > 	/**
> > > > > 	 * arch_atomic_inc_return_release()
> > > > > 	 *
> > > > > 	 * [ full kerneldoc block here ]
> > > > > 	 */
> > > > > 	#if defined(arch_atomic_inc_return_release)
> > > > > 	/* defined in arch code */
> > > > > 	#elif defined(arch_atomic_inc_return_relaxed)
> > > > > 	[ define in terms of arch_atomic_inc_return_relaxed ]
> > > > > 	#elif defined(arch_atomic_inc_return)
> > > > > 	[ define in terms of arch_atomic_inc_return ]
> > > > > 	#else
> > > > > 	[ define in terms of arch_atomic_fetch_inc_release ]
> > > > > 	#endif
> > > > > 
> > > > > ... with similar for the mandatory ops that each arch must provide, e.g.
> > > > > 
> > > > > 	/**
> > > > > 	 * arch_atomic_or()
> > > > > 	 *
> > > > > 	 * [ full kerneldoc block here ]
> > > > > 	 */
> > > > > 	/* arch_atomic_or() is mandatory -- architectures must define it! */
> > > > > 
> > > > > I had a go at that restructuring today, and while local build testing indicates
> > > > > I haven't got it quite right, I think it's possible:
> > > > > 
> > > > >   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> > > > > 
> > > > > Does that sound ok to you?
> > > > 
> > > > At first glance, it appears that your "TODO" locations have the same
> > > > information that I was using, so it should not be hard for me to adapt the
> > > > current kernel-doc generation to your new scheme.  (Famous last words!)
> > > 
> > > Great!
> > > 
> > > > Plus having the kernel-doc generation all in one place does have some
> > > > serious attractions.
> > > 
> > > :)
> > > 
> > > > I will continue maintaining my current stack, but would of course be
> > > > happy to port it on top of your refactoring.  If it turns out that
> > > > the refactoring will take a long time, we can discuss what to do in
> > > > the meantime.  But here is hoping that the refactoring goes smoothly!
> > > > That would be easier all around.  ;-)
> > > 
> > > FWIW, I think that's working now; every cross-build I've tried works.
> > > 
> > > I've updated the branch at:
> > > 
> > >   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> > > 
> > > Tagged as:
> > > 
> > >   atomics-fallback-rework-20230512
> > 
> > Thank you very much!
> > 
> > I expect to send v2 of my original late today on the perhaps unlikely
> > off-chance that someone might be interested in reviewing the verbiage.
> 
> I'll be more than happy to, though I suspect "late today" is far too late today
> for me in UK time terms, so I probably won't look until Monday.

Works for me!

> > More to the point, I have started porting my changes on top of your
> > stack.  My thought is to have a separate "."-included script that does
> > the kernel-doc work.
> 
> I was thinking that we'd have a gen_kerneldoc(...) shell function (probably in
> atomic-tbl.sh), but that's an easy thing to refactor after v2, so either way is
> fine for now!

Good point, will make that happen.  Easy to move the code, so might
as well be v1.  ;-)

> > I am also thinking in terms of putting the kernel-doc generation into
> > an "else" clause to the "is mandatory" check, and leaving the kernel-doc
> > for the mandatory functions in arch/x86/include/asm/atomic.h.
> 
> My thinking was that all the kernel-doc bits should live in the common header
> so that they're all easy to find when looking at the source code, and since if
> feels a bit weird to have to look into arch/x86/ to figure out the semantics of
> a function on !x86.
> 
> That said, if that's painful for some reason, please go with the easiest option
> for now and we can figure out how to attack it for v3. :)

I will give it a shot.

							Thanx, Paul
  
Paul E. McKenney May 13, 2023, 2:11 a.m. UTC | #17
On Fri, May 12, 2023 at 11:42:02AM -0700, Paul E. McKenney wrote:
> On Fri, May 12, 2023 at 06:03:26PM +0100, Mark Rutland wrote:
> > On Fri, May 12, 2023 at 09:01:27AM -0700, Paul E. McKenney wrote:
> > > On Fri, May 12, 2023 at 02:18:48PM +0100, Mark Rutland wrote:
> > > > On Thu, May 11, 2023 at 12:12:16PM -0700, Paul E. McKenney wrote:
> > > > > On Thu, May 11, 2023 at 06:10:00PM +0100, Mark Rutland wrote:
> > > > > > I think that we can restructure the ifdeffery so that each ordering variant
> > > > > > gets its own ifdeffery, and then we could place the kerneldoc immediately above
> > > > > > that, e.g.
> > > > > > 
> > > > > > 	/**
> > > > > > 	 * arch_atomic_inc_return_release()
> > > > > > 	 *
> > > > > > 	 * [ full kerneldoc block here ]
> > > > > > 	 */
> > > > > > 	#if defined(arch_atomic_inc_return_release)
> > > > > > 	/* defined in arch code */
> > > > > > 	#elif defined(arch_atomic_inc_return_relaxed)
> > > > > > 	[ define in terms of arch_atomic_inc_return_relaxed ]
> > > > > > 	#elif defined(arch_atomic_inc_return)
> > > > > > 	[ define in terms of arch_atomic_inc_return ]
> > > > > > 	#else
> > > > > > 	[ define in terms of arch_atomic_fetch_inc_release ]
> > > > > > 	#endif
> > > > > > 
> > > > > > ... with similar for the mandatory ops that each arch must provide, e.g.
> > > > > > 
> > > > > > 	/**
> > > > > > 	 * arch_atomic_or()
> > > > > > 	 *
> > > > > > 	 * [ full kerneldoc block here ]
> > > > > > 	 */
> > > > > > 	/* arch_atomic_or() is mandatory -- architectures must define it! */
> > > > > > 
> > > > > > I had a go at that restructuring today, and while local build testing indicates
> > > > > > I haven't got it quite right, I think it's possible:
> > > > > > 
> > > > > >   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> > > > > > 
> > > > > > Does that sound ok to you?
> > > > > 
> > > > > At first glance, it appears that your "TODO" locations have the same
> > > > > information that I was using, so it should not be hard for me to adapt the
> > > > > current kernel-doc generation to your new scheme.  (Famous last words!)
> > > > 
> > > > Great!
> > > > 
> > > > > Plus having the kernel-doc generation all in one place does have some
> > > > > serious attractions.
> > > > 
> > > > :)
> > > > 
> > > > > I will continue maintaining my current stack, but would of course be
> > > > > happy to port it on top of your refactoring.  If it turns out that
> > > > > the refactoring will take a long time, we can discuss what to do in
> > > > > the meantime.  But here is hoping that the refactoring goes smoothly!
> > > > > That would be easier all around.  ;-)
> > > > 
> > > > FWIW, I think that's working now; every cross-build I've tried works.
> > > > 
> > > > I've updated the branch at:
> > > > 
> > > >   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=atomics/fallback-rework
> > > > 
> > > > Tagged as:
> > > > 
> > > >   atomics-fallback-rework-20230512
> > > 
> > > Thank you very much!
> > > 
> > > I expect to send v2 of my original late today on the perhaps unlikely
> > > off-chance that someone might be interested in reviewing the verbiage.
> > 
> > I'll be more than happy to, though I suspect "late today" is far too late today
> > for me in UK time terms, so I probably won't look until Monday.
> 
> Works for me!

Except that cleaning up the old version proved more obnoxious than
creating a new one, adding more evidence behind the wisdom of your
reworkin.  So no v2 of the previous series, for the moment, at least.

> > > More to the point, I have started porting my changes on top of your
> > > stack.  My thought is to have a separate "."-included script that does
> > > the kernel-doc work.
> > 
> > I was thinking that we'd have a gen_kerneldoc(...) shell function (probably in
> > atomic-tbl.sh), but that's an easy thing to refactor after v2, so either way is
> > fine for now!
> 
> Good point, will make that happen.  Easy to move the code, so might
> as well be v1.  ;-)
> 
> > > I am also thinking in terms of putting the kernel-doc generation into
> > > an "else" clause to the "is mandatory" check, and leaving the kernel-doc
> > > for the mandatory functions in arch/x86/include/asm/atomic.h.
> > 
> > My thinking was that all the kernel-doc bits should live in the common header
> > so that they're all easy to find when looking at the source code, and since if
> > feels a bit weird to have to look into arch/x86/ to figure out the semantics of
> > a function on !x86.
> > 
> > That said, if that's painful for some reason, please go with the easiest option
> > for now and we can figure out how to attack it for v3. :)
> 
> I will give it a shot.

And here is a rough first cut:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git tags/fallback-rework-kernel-doc.2023.05.12a

Or via HTML:

https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git/log/?h=fallback-rework-kernel-doc.2023.05.12a

Thoughts?

In the meantime, enjoy the weekend!

							Thanx, Paul
  
Akira Yokosawa May 13, 2023, 11:58 p.m. UTC | #18
Hi,

On Fri, 12 May 2023 19:11:15 -0700, Paul E. McKenney wrote:
[...]

> 
> And here is a rough first cut:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git tags/fallback-rework-kernel-doc.2023.05.12a
> 
> Or via HTML:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git/log/?h=fallback-rework-kernel-doc.2023.05.12a

Running "./scripts/kernel-doc -none include/linux/atomic/atomic-arch-fallback.h"
on the tag emits a lot of warnings.

Looks like there are kernel-doc comments who don't have a corresponding
function signature next to them.

    /**
     * function_name() - Brief description of function.
     * @arg1: Describe the first argument.
     * @arg2: Describe the second argument.
     *        One can provide multiple line descriptions
     *        for arguments.
     *
     * A longer description, with more discussion of the function function_name()
     * that might be useful to those using or modifying it. Begins with an
     * empty comment line, and may include additional embedded empty
     * comment lines.
     */
    int function_name(int arg1, int arg2)  <---

Note that the kernel-doc script ignores #ifdef -- #else.

BTW, I couldn't checkout the tag so downloaded the tar ball via
HTML.

        Thanks, Akira

> 
> Thoughts?
> 
> In the meantime, enjoy the weekend!
> 
> 							Thanx, Paul
  
Paul E. McKenney May 14, 2023, 1:14 a.m. UTC | #19
On Sun, May 14, 2023 at 08:58:00AM +0900, Akira Yokosawa wrote:
> Hi,
> 
> On Fri, 12 May 2023 19:11:15 -0700, Paul E. McKenney wrote:
> [...]
> 
> > 
> > And here is a rough first cut:
> > 
> > git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git tags/fallback-rework-kernel-doc.2023.05.12a
> > 
> > Or via HTML:
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git/log/?h=fallback-rework-kernel-doc.2023.05.12a
> 
> Running "./scripts/kernel-doc -none include/linux/atomic/atomic-arch-fallback.h"
> on the tag emits a lot of warnings.
> 
> Looks like there are kernel-doc comments who don't have a corresponding
> function signature next to them.
> 
>     /**
>      * function_name() - Brief description of function.
>      * @arg1: Describe the first argument.
>      * @arg2: Describe the second argument.
>      *        One can provide multiple line descriptions
>      *        for arguments.
>      *
>      * A longer description, with more discussion of the function function_name()
>      * that might be useful to those using or modifying it. Begins with an
>      * empty comment line, and may include additional embedded empty
>      * comment lines.
>      */
>     int function_name(int arg1, int arg2)  <---
> 
> Note that the kernel-doc script ignores #ifdef -- #else.

Me, I was thinking in terms of making this diagnostic ignore
include/linux/atomic/atomic-arch-fallback.h.  ;-)

The actual definitions are off in architecture-specific files, and
the kernel-doc headers could be left there.  But there are benefits to
automatically generating all of them.

Another approach might be to put a "it is OK for the definition to
be elsewhere" comment following those kernel-doc headers.

Any other ways to make this work?  For me, the option of making this
diagnostic ignore include/linux/atomic/atomic-arch-fallback.h has
considerable attraction.

> BTW, I couldn't checkout the tag so downloaded the tar ball via
> HTML.

Tags can be a bit annoying in that way.  I will provide a branch next
time.

							Thanx, Paul

>         Thanks, Akira
> 
> > 
> > Thoughts?
> > 
> > In the meantime, enjoy the weekend!
> > 
> > 							Thanx, Paul
  
Mark Rutland May 16, 2023, 4:52 p.m. UTC | #20
Hi Paul,

On Sat, May 13, 2023 at 06:14:36PM -0700, Paul E. McKenney wrote:
> On Sun, May 14, 2023 at 08:58:00AM +0900, Akira Yokosawa wrote:
> > Running "./scripts/kernel-doc -none include/linux/atomic/atomic-arch-fallback.h"
> > on the tag emits a lot of warnings.
> > 
> > Looks like there are kernel-doc comments who don't have a corresponding
> > function signature next to them.
> > 
> >     /**
> >      * function_name() - Brief description of function.
> >      * @arg1: Describe the first argument.
> >      * @arg2: Describe the second argument.
> >      *        One can provide multiple line descriptions
> >      *        for arguments.
> >      *
> >      * A longer description, with more discussion of the function function_name()
> >      * that might be useful to those using or modifying it. Begins with an
> >      * empty comment line, and may include additional embedded empty
> >      * comment lines.
> >      */
> >     int function_name(int arg1, int arg2)  <---
> > 
> > Note that the kernel-doc script ignores #ifdef -- #else.
> 
> Me, I was thinking in terms of making this diagnostic ignore
> include/linux/atomic/atomic-arch-fallback.h.  ;-)
> 
> The actual definitions are off in architecture-specific files, and
> the kernel-doc headers could be left there.  But there are benefits to
> automatically generating all of them.
> 
> Another approach might be to put a "it is OK for the definition to
> be elsewhere" comment following those kernel-doc headers.
> 
> Any other ways to make this work?

I've spent the last day or so playing with this, and I think we can do this by
relegating the arch_atomic*() functions to an implementation detail (and not
documenting those with kerneldoc), and having a raw_atomic*() layer where we
flesh out the API, where each can have a mandatory function definition as
below:

/**
 * raw_atomic_fetch_inc_release() - does a thing atomically
 *
 * TODO: fill this in
 *
 * This is a version of atomic_fetch_inc_release() which is safe to use in
 * noinstr code. Unless instrumentation needs to be avoided,
 * atomic_fetch_inc_release() should be used in preference.
 */
static __always_inline int
raw_atomic_fetch_inc_release(atomic_t *v)
{
#if defined(arch_atomic_fetch_inc_release)
        return arch_atomic_fetch_inc_release(v)
#elif defined(arch_atomic_fetch_inc_relaxed)
        __atomic_release_fence();
        return arch_atomic_fetch_inc_relaxed(v);
#elif defined(arch_atomic_fetch_inc)
        return arch_atomic_fetch_inc(v)
#else   
        return raw_atomic_fetch_add_release(1, v);
#endif
}

... and likewise we can add comments for the regular instrumented atomics.

I've pushed out the WIP patches to my atomics/fallback-rework branch; if you're
happy to give me another day or two I can get a bit further.

> For me, the option of making this
> diagnostic ignore include/linux/atomic/atomic-arch-fallback.h has
> considerable attraction.

It's certainly appealing...

Thanks,
Mark.
  
Paul E. McKenney May 16, 2023, 6:42 p.m. UTC | #21
On Tue, May 16, 2023 at 05:52:03PM +0100, Mark Rutland wrote:
> Hi Paul,
> 
> On Sat, May 13, 2023 at 06:14:36PM -0700, Paul E. McKenney wrote:
> > On Sun, May 14, 2023 at 08:58:00AM +0900, Akira Yokosawa wrote:
> > > Running "./scripts/kernel-doc -none include/linux/atomic/atomic-arch-fallback.h"
> > > on the tag emits a lot of warnings.
> > > 
> > > Looks like there are kernel-doc comments who don't have a corresponding
> > > function signature next to them.
> > > 
> > >     /**
> > >      * function_name() - Brief description of function.
> > >      * @arg1: Describe the first argument.
> > >      * @arg2: Describe the second argument.
> > >      *        One can provide multiple line descriptions
> > >      *        for arguments.
> > >      *
> > >      * A longer description, with more discussion of the function function_name()
> > >      * that might be useful to those using or modifying it. Begins with an
> > >      * empty comment line, and may include additional embedded empty
> > >      * comment lines.
> > >      */
> > >     int function_name(int arg1, int arg2)  <---
> > > 
> > > Note that the kernel-doc script ignores #ifdef -- #else.
> > 
> > Me, I was thinking in terms of making this diagnostic ignore
> > include/linux/atomic/atomic-arch-fallback.h.  ;-)
> > 
> > The actual definitions are off in architecture-specific files, and
> > the kernel-doc headers could be left there.  But there are benefits to
> > automatically generating all of them.
> > 
> > Another approach might be to put a "it is OK for the definition to
> > be elsewhere" comment following those kernel-doc headers.
> > 
> > Any other ways to make this work?
> 
> I've spent the last day or so playing with this, and I think we can do this by
> relegating the arch_atomic*() functions to an implementation detail (and not
> documenting those with kerneldoc), and having a raw_atomic*() layer where we
> flesh out the API, where each can have a mandatory function definition as
> below:
> 
> /**
>  * raw_atomic_fetch_inc_release() - does a thing atomically
>  *
>  * TODO: fill this in
>  *
>  * This is a version of atomic_fetch_inc_release() which is safe to use in
>  * noinstr code. Unless instrumentation needs to be avoided,
>  * atomic_fetch_inc_release() should be used in preference.
>  */
> static __always_inline int
> raw_atomic_fetch_inc_release(atomic_t *v)
> {
> #if defined(arch_atomic_fetch_inc_release)
>         return arch_atomic_fetch_inc_release(v)
> #elif defined(arch_atomic_fetch_inc_relaxed)
>         __atomic_release_fence();
>         return arch_atomic_fetch_inc_relaxed(v);
> #elif defined(arch_atomic_fetch_inc)
>         return arch_atomic_fetch_inc(v)
> #else   
>         return raw_atomic_fetch_add_release(1, v);
> #endif
> }
> 
> ... and likewise we can add comments for the regular instrumented atomics.

I do like that approach!  It should be easy to adapt the kernel-doc
scripting to this.

> I've pushed out the WIP patches to my atomics/fallback-rework branch; if you're
> happy to give me another day or two I can get a bit further.

An RCU issue currently has me by the ankle, so I am quite happy to give
you a day or two.  ;-)

Just FYI, I will be in the air this coming Friday, your time.

> > For me, the option of making this
> > diagnostic ignore include/linux/atomic/atomic-arch-fallback.h has
> > considerable attraction.
> 
> It's certainly appealing...

But I do like your approach of simply always having the function prototype
available.  ;-)

							Thanx, Paul
  

Patch

diff --git a/include/linux/atomic/atomic-arch-fallback.h b/include/linux/atomic/atomic-arch-fallback.h
index 41aa94f0aacd..2d56726f8662 100644
--- a/include/linux/atomic/atomic-arch-fallback.h
+++ b/include/linux/atomic/atomic-arch-fallback.h
@@ -639,13 +639,7 @@  arch_atomic_inc_return_relaxed(atomic_t *v)
 #else /* arch_atomic_inc_return_relaxed */
 
 #ifndef arch_atomic_inc_return_acquire
-/**
- * arch_atomic_inc_return_acquire - Atomic inc with acquire ordering
- * @v: pointer of type atomic_t
- *
- * Atomically increment @v using acquire ordering.
- * Return new value.
- */
+// Fallback acquire omitting duplicate arch_atomic_inc_return_acquire() kernel-doc header.
 static __always_inline int
 arch_atomic_inc_return_acquire(atomic_t *v)
 {
@@ -657,13 +651,7 @@  arch_atomic_inc_return_acquire(atomic_t *v)
 #endif
 
 #ifndef arch_atomic_inc_return_release
-/**
- * arch_atomic_inc_return_release - Atomic inc with release ordering
- * @v: pointer of type atomic_t
- *
- * Atomically increment @v using release ordering.
- * Return new value.
- */
+// Fallback release omitting duplicate arch_atomic_inc_return_release() kernel-doc header.
 static __always_inline int
 arch_atomic_inc_return_release(atomic_t *v)
 {
@@ -674,13 +662,7 @@  arch_atomic_inc_return_release(atomic_t *v)
 #endif
 
 #ifndef arch_atomic_inc_return
-/**
- * arch_atomic_inc_return - Atomic inc with full ordering
- * @v: pointer of type atomic_t
- *
- * Atomically increment @v using full ordering.
- * Return new value.
- */
+// Fallback fence omitting duplicate arch_atomic_inc_return() kernel-doc header.
 static __always_inline int
 arch_atomic_inc_return(atomic_t *v)
 {
@@ -769,13 +751,7 @@  arch_atomic_fetch_inc_relaxed(atomic_t *v)
 #else /* arch_atomic_fetch_inc_relaxed */
 
 #ifndef arch_atomic_fetch_inc_acquire
-/**
- * arch_atomic_fetch_inc_acquire - Atomic inc with acquire ordering
- * @v: pointer of type atomic_t
- *
- * Atomically increment @v using acquire ordering.
- * Return old value.
- */
+// Fallback acquire omitting duplicate arch_atomic_fetch_inc_acquire() kernel-doc header.
 static __always_inline int
 arch_atomic_fetch_inc_acquire(atomic_t *v)
 {
@@ -787,13 +763,7 @@  arch_atomic_fetch_inc_acquire(atomic_t *v)
 #endif
 
 #ifndef arch_atomic_fetch_inc_release
-/**
- * arch_atomic_fetch_inc_release - Atomic inc with release ordering
- * @v: pointer of type atomic_t
- *
- * Atomically increment @v using release ordering.
- * Return old value.
- */
+// Fallback release omitting duplicate arch_atomic_fetch_inc_release() kernel-doc header.
 static __always_inline int
 arch_atomic_fetch_inc_release(atomic_t *v)
 {
@@ -804,13 +774,7 @@  arch_atomic_fetch_inc_release(atomic_t *v)
 #endif
 
 #ifndef arch_atomic_fetch_inc
-/**
- * arch_atomic_fetch_inc - Atomic inc with full ordering
- * @v: pointer of type atomic_t
- *
- * Atomically increment @v using full ordering.
- * Return old value.
- */
+// Fallback fence omitting duplicate arch_atomic_fetch_inc() kernel-doc header.
 static __always_inline int
 arch_atomic_fetch_inc(atomic_t *v)
 {
@@ -915,13 +879,7 @@  arch_atomic_dec_return_relaxed(atomic_t *v)
 #else /* arch_atomic_dec_return_relaxed */
 
 #ifndef arch_atomic_dec_return_acquire
-/**
- * arch_atomic_dec_return_acquire - Atomic dec with acquire ordering
- * @v: pointer of type atomic_t
- *
- * Atomically decrement @v using acquire ordering.
- * Return new value.
- */
+// Fallback acquire omitting duplicate arch_atomic_dec_return_acquire() kernel-doc header.
 static __always_inline int
 arch_atomic_dec_return_acquire(atomic_t *v)
 {
@@ -933,13 +891,7 @@  arch_atomic_dec_return_acquire(atomic_t *v)
 #endif
 
 #ifndef arch_atomic_dec_return_release
-/**
- * arch_atomic_dec_return_release - Atomic dec with release ordering
- * @v: pointer of type atomic_t
- *
- * Atomically decrement @v using release ordering.
- * Return new value.
- */
+// Fallback release omitting duplicate arch_atomic_dec_return_release() kernel-doc header.
 static __always_inline int
 arch_atomic_dec_return_release(atomic_t *v)
 {
@@ -950,13 +902,7 @@  arch_atomic_dec_return_release(atomic_t *v)
 #endif
 
 #ifndef arch_atomic_dec_return
-/**
- * arch_atomic_dec_return - Atomic dec with full ordering
- * @v: pointer of type atomic_t
- *
- * Atomically decrement @v using full ordering.
- * Return new value.
- */
+// Fallback fence omitting duplicate arch_atomic_dec_return() kernel-doc header.
 static __always_inline int
 arch_atomic_dec_return(atomic_t *v)
 {
@@ -1045,13 +991,7 @@  arch_atomic_fetch_dec_relaxed(atomic_t *v)
 #else /* arch_atomic_fetch_dec_relaxed */
 
 #ifndef arch_atomic_fetch_dec_acquire
-/**
- * arch_atomic_fetch_dec_acquire - Atomic dec with acquire ordering
- * @v: pointer of type atomic_t
- *
- * Atomically decrement @v using acquire ordering.
- * Return old value.
- */
+// Fallback acquire omitting duplicate arch_atomic_fetch_dec_acquire() kernel-doc header.
 static __always_inline int
 arch_atomic_fetch_dec_acquire(atomic_t *v)
 {
@@ -1063,13 +1003,7 @@  arch_atomic_fetch_dec_acquire(atomic_t *v)
 #endif
 
 #ifndef arch_atomic_fetch_dec_release
-/**
- * arch_atomic_fetch_dec_release - Atomic dec with release ordering
- * @v: pointer of type atomic_t
- *
- * Atomically decrement @v using release ordering.
- * Return old value.
- */
+// Fallback release omitting duplicate arch_atomic_fetch_dec_release() kernel-doc header.
 static __always_inline int
 arch_atomic_fetch_dec_release(atomic_t *v)
 {
@@ -1080,13 +1014,7 @@  arch_atomic_fetch_dec_release(atomic_t *v)
 #endif
 
 #ifndef arch_atomic_fetch_dec
-/**
- * arch_atomic_fetch_dec - Atomic dec with full ordering
- * @v: pointer of type atomic_t
- *
- * Atomically decrement @v using full ordering.
- * Return old value.
- */
+// Fallback fence omitting duplicate arch_atomic_fetch_dec() kernel-doc header.
 static __always_inline int
 arch_atomic_fetch_dec(atomic_t *v)
 {
@@ -1262,14 +1190,7 @@  arch_atomic_fetch_andnot_relaxed(int i, atomic_t *v)
 #else /* arch_atomic_fetch_andnot_relaxed */
 
 #ifndef arch_atomic_fetch_andnot_acquire
-/**
- * arch_atomic_fetch_andnot_acquire - Atomic andnot with acquire ordering
- * @i: value to complement then AND
- * @v: pointer of type atomic_t
- *
- * Atomically complement then AND @i with @v using acquire ordering.
- * Return old value.
- */
+// Fallback acquire omitting duplicate arch_atomic_fetch_andnot_acquire() kernel-doc header.
 static __always_inline int
 arch_atomic_fetch_andnot_acquire(int i, atomic_t *v)
 {
@@ -1281,14 +1202,7 @@  arch_atomic_fetch_andnot_acquire(int i, atomic_t *v)
 #endif
 
 #ifndef arch_atomic_fetch_andnot_release
-/**
- * arch_atomic_fetch_andnot_release - Atomic andnot with release ordering
- * @i: value to complement then AND
- * @v: pointer of type atomic_t
- *
- * Atomically complement then AND @i with @v using release ordering.
- * Return old value.
- */
+// Fallback release omitting duplicate arch_atomic_fetch_andnot_release() kernel-doc header.
 static __always_inline int
 arch_atomic_fetch_andnot_release(int i, atomic_t *v)
 {
@@ -1299,14 +1213,7 @@  arch_atomic_fetch_andnot_release(int i, atomic_t *v)
 #endif
 
 #ifndef arch_atomic_fetch_andnot
-/**
- * arch_atomic_fetch_andnot - Atomic andnot with full ordering
- * @i: value to complement then AND
- * @v: pointer of type atomic_t
- *
- * Atomically complement then AND @i with @v using full ordering.
- * Return old value.
- */
+// Fallback fence omitting duplicate arch_atomic_fetch_andnot() kernel-doc header.
 static __always_inline int
 arch_atomic_fetch_andnot(int i, atomic_t *v)
 {
@@ -1699,18 +1606,7 @@  arch_atomic_try_cmpxchg_relaxed(atomic_t *v, int *old, int new)
 #else /* arch_atomic_try_cmpxchg_relaxed */
 
 #ifndef arch_atomic_try_cmpxchg_acquire
-/**
- * arch_atomic_try_cmpxchg_acquire - Atomic try_cmpxchg with acquire ordering
- * @v: pointer of type atomic_t
- * @old: desired old value to match
- * @new: new value to put in
- *
- * Atomically compares @new to *@v, and if equal,
- * stores @new to *@v, providing acquire ordering.
- * Returns @true if the cmpxchg operation succeeded,
- * and false otherwise.  Either way, stores the old
- * value of *@v to *@old.
- */
+// Fallback acquire omitting duplicate arch_atomic_try_cmpxchg_acquire() kernel-doc header.
 static __always_inline bool
 arch_atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
 {
@@ -1722,18 +1618,7 @@  arch_atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
 #endif
 
 #ifndef arch_atomic_try_cmpxchg_release
-/**
- * arch_atomic_try_cmpxchg_release - Atomic try_cmpxchg with release ordering
- * @v: pointer of type atomic_t
- * @old: desired old value to match
- * @new: new value to put in
- *
- * Atomically compares @new to *@v, and if equal,
- * stores @new to *@v, providing release ordering.
- * Returns @true if the cmpxchg operation succeeded,
- * and false otherwise.  Either way, stores the old
- * value of *@v to *@old.
- */
+// Fallback release omitting duplicate arch_atomic_try_cmpxchg_release() kernel-doc header.
 static __always_inline bool
 arch_atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
 {
@@ -1744,18 +1629,7 @@  arch_atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
 #endif
 
 #ifndef arch_atomic_try_cmpxchg
-/**
- * arch_atomic_try_cmpxchg - Atomic try_cmpxchg with full ordering
- * @v: pointer of type atomic_t
- * @old: desired old value to match
- * @new: new value to put in
- *
- * Atomically compares @new to *@v, and if equal,
- * stores @new to *@v, providing full ordering.
- * Returns @true if the cmpxchg operation succeeded,
- * and false otherwise.  Either way, stores the old
- * value of *@v to *@old.
- */
+// Fallback fence omitting duplicate arch_atomic_try_cmpxchg() kernel-doc header.
 static __always_inline bool
 arch_atomic_try_cmpxchg(atomic_t *v, int *old, int new)
 {
@@ -1900,15 +1774,7 @@  arch_atomic_add_negative_relaxed(int i, atomic_t *v)
 #else /* arch_atomic_add_negative_relaxed */
 
 #ifndef arch_atomic_add_negative_acquire
-/**
- * arch_atomic_add_negative_acquire - Atomic add_negative with acquire ordering
- * @i: value to add
- * @v: pointer of type atomic_t
- *
- * Atomically add @i with @v using acquire ordering.
- * Return @true if the result is negative, or @false when
- * the result is greater than or equal to zero.
- */
+// Fallback acquire omitting duplicate arch_atomic_add_negative_acquire() kernel-doc header.
 static __always_inline bool
 arch_atomic_add_negative_acquire(int i, atomic_t *v)
 {
@@ -1920,15 +1786,7 @@  arch_atomic_add_negative_acquire(int i, atomic_t *v)
 #endif
 
 #ifndef arch_atomic_add_negative_release
-/**
- * arch_atomic_add_negative_release - Atomic add_negative with release ordering
- * @i: value to add
- * @v: pointer of type atomic_t
- *
- * Atomically add @i with @v using release ordering.
- * Return @true if the result is negative, or @false when
- * the result is greater than or equal to zero.
- */
+// Fallback release omitting duplicate arch_atomic_add_negative_release() kernel-doc header.
 static __always_inline bool
 arch_atomic_add_negative_release(int i, atomic_t *v)
 {
@@ -1939,15 +1797,7 @@  arch_atomic_add_negative_release(int i, atomic_t *v)
 #endif
 
 #ifndef arch_atomic_add_negative
-/**
- * arch_atomic_add_negative - Atomic add_negative with full ordering
- * @i: value to add
- * @v: pointer of type atomic_t
- *
- * Atomically add @i with @v using full ordering.
- * Return @true if the result is negative, or @false when
- * the result is greater than or equal to zero.
- */
+// Fallback fence omitting duplicate arch_atomic_add_negative() kernel-doc header.
 static __always_inline bool
 arch_atomic_add_negative(int i, atomic_t *v)
 {
@@ -2500,13 +2350,7 @@  arch_atomic64_inc_return_relaxed(atomic64_t *v)
 #else /* arch_atomic64_inc_return_relaxed */
 
 #ifndef arch_atomic64_inc_return_acquire
-/**
- * arch_atomic64_inc_return_acquire - Atomic inc with acquire ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically increment @v using acquire ordering.
- * Return new value.
- */
+// Fallback acquire omitting duplicate arch_atomic64_inc_return_acquire() kernel-doc header.
 static __always_inline s64
 arch_atomic64_inc_return_acquire(atomic64_t *v)
 {
@@ -2518,13 +2362,7 @@  arch_atomic64_inc_return_acquire(atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_inc_return_release
-/**
- * arch_atomic64_inc_return_release - Atomic inc with release ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically increment @v using release ordering.
- * Return new value.
- */
+// Fallback release omitting duplicate arch_atomic64_inc_return_release() kernel-doc header.
 static __always_inline s64
 arch_atomic64_inc_return_release(atomic64_t *v)
 {
@@ -2535,13 +2373,7 @@  arch_atomic64_inc_return_release(atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_inc_return
-/**
- * arch_atomic64_inc_return - Atomic inc with full ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically increment @v using full ordering.
- * Return new value.
- */
+// Fallback fence omitting duplicate arch_atomic64_inc_return() kernel-doc header.
 static __always_inline s64
 arch_atomic64_inc_return(atomic64_t *v)
 {
@@ -2630,13 +2462,7 @@  arch_atomic64_fetch_inc_relaxed(atomic64_t *v)
 #else /* arch_atomic64_fetch_inc_relaxed */
 
 #ifndef arch_atomic64_fetch_inc_acquire
-/**
- * arch_atomic64_fetch_inc_acquire - Atomic inc with acquire ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically increment @v using acquire ordering.
- * Return old value.
- */
+// Fallback acquire omitting duplicate arch_atomic64_fetch_inc_acquire() kernel-doc header.
 static __always_inline s64
 arch_atomic64_fetch_inc_acquire(atomic64_t *v)
 {
@@ -2648,13 +2474,7 @@  arch_atomic64_fetch_inc_acquire(atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_fetch_inc_release
-/**
- * arch_atomic64_fetch_inc_release - Atomic inc with release ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically increment @v using release ordering.
- * Return old value.
- */
+// Fallback release omitting duplicate arch_atomic64_fetch_inc_release() kernel-doc header.
 static __always_inline s64
 arch_atomic64_fetch_inc_release(atomic64_t *v)
 {
@@ -2665,13 +2485,7 @@  arch_atomic64_fetch_inc_release(atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_fetch_inc
-/**
- * arch_atomic64_fetch_inc - Atomic inc with full ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically increment @v using full ordering.
- * Return old value.
- */
+// Fallback fence omitting duplicate arch_atomic64_fetch_inc() kernel-doc header.
 static __always_inline s64
 arch_atomic64_fetch_inc(atomic64_t *v)
 {
@@ -2776,13 +2590,7 @@  arch_atomic64_dec_return_relaxed(atomic64_t *v)
 #else /* arch_atomic64_dec_return_relaxed */
 
 #ifndef arch_atomic64_dec_return_acquire
-/**
- * arch_atomic64_dec_return_acquire - Atomic dec with acquire ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically decrement @v using acquire ordering.
- * Return new value.
- */
+// Fallback acquire omitting duplicate arch_atomic64_dec_return_acquire() kernel-doc header.
 static __always_inline s64
 arch_atomic64_dec_return_acquire(atomic64_t *v)
 {
@@ -2794,13 +2602,7 @@  arch_atomic64_dec_return_acquire(atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_dec_return_release
-/**
- * arch_atomic64_dec_return_release - Atomic dec with release ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically decrement @v using release ordering.
- * Return new value.
- */
+// Fallback release omitting duplicate arch_atomic64_dec_return_release() kernel-doc header.
 static __always_inline s64
 arch_atomic64_dec_return_release(atomic64_t *v)
 {
@@ -2811,13 +2613,7 @@  arch_atomic64_dec_return_release(atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_dec_return
-/**
- * arch_atomic64_dec_return - Atomic dec with full ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically decrement @v using full ordering.
- * Return new value.
- */
+// Fallback fence omitting duplicate arch_atomic64_dec_return() kernel-doc header.
 static __always_inline s64
 arch_atomic64_dec_return(atomic64_t *v)
 {
@@ -2906,13 +2702,7 @@  arch_atomic64_fetch_dec_relaxed(atomic64_t *v)
 #else /* arch_atomic64_fetch_dec_relaxed */
 
 #ifndef arch_atomic64_fetch_dec_acquire
-/**
- * arch_atomic64_fetch_dec_acquire - Atomic dec with acquire ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically decrement @v using acquire ordering.
- * Return old value.
- */
+// Fallback acquire omitting duplicate arch_atomic64_fetch_dec_acquire() kernel-doc header.
 static __always_inline s64
 arch_atomic64_fetch_dec_acquire(atomic64_t *v)
 {
@@ -2924,13 +2714,7 @@  arch_atomic64_fetch_dec_acquire(atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_fetch_dec_release
-/**
- * arch_atomic64_fetch_dec_release - Atomic dec with release ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically decrement @v using release ordering.
- * Return old value.
- */
+// Fallback release omitting duplicate arch_atomic64_fetch_dec_release() kernel-doc header.
 static __always_inline s64
 arch_atomic64_fetch_dec_release(atomic64_t *v)
 {
@@ -2941,13 +2725,7 @@  arch_atomic64_fetch_dec_release(atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_fetch_dec
-/**
- * arch_atomic64_fetch_dec - Atomic dec with full ordering
- * @v: pointer of type atomic64_t
- *
- * Atomically decrement @v using full ordering.
- * Return old value.
- */
+// Fallback fence omitting duplicate arch_atomic64_fetch_dec() kernel-doc header.
 static __always_inline s64
 arch_atomic64_fetch_dec(atomic64_t *v)
 {
@@ -3123,14 +2901,7 @@  arch_atomic64_fetch_andnot_relaxed(s64 i, atomic64_t *v)
 #else /* arch_atomic64_fetch_andnot_relaxed */
 
 #ifndef arch_atomic64_fetch_andnot_acquire
-/**
- * arch_atomic64_fetch_andnot_acquire - Atomic andnot with acquire ordering
- * @i: value to complement then AND
- * @v: pointer of type atomic64_t
- *
- * Atomically complement then AND @i with @v using acquire ordering.
- * Return old value.
- */
+// Fallback acquire omitting duplicate arch_atomic64_fetch_andnot_acquire() kernel-doc header.
 static __always_inline s64
 arch_atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
 {
@@ -3142,14 +2913,7 @@  arch_atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_fetch_andnot_release
-/**
- * arch_atomic64_fetch_andnot_release - Atomic andnot with release ordering
- * @i: value to complement then AND
- * @v: pointer of type atomic64_t
- *
- * Atomically complement then AND @i with @v using release ordering.
- * Return old value.
- */
+// Fallback release omitting duplicate arch_atomic64_fetch_andnot_release() kernel-doc header.
 static __always_inline s64
 arch_atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
 {
@@ -3160,14 +2924,7 @@  arch_atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_fetch_andnot
-/**
- * arch_atomic64_fetch_andnot - Atomic andnot with full ordering
- * @i: value to complement then AND
- * @v: pointer of type atomic64_t
- *
- * Atomically complement then AND @i with @v using full ordering.
- * Return old value.
- */
+// Fallback fence omitting duplicate arch_atomic64_fetch_andnot() kernel-doc header.
 static __always_inline s64
 arch_atomic64_fetch_andnot(s64 i, atomic64_t *v)
 {
@@ -3560,18 +3317,7 @@  arch_atomic64_try_cmpxchg_relaxed(atomic64_t *v, s64 *old, s64 new)
 #else /* arch_atomic64_try_cmpxchg_relaxed */
 
 #ifndef arch_atomic64_try_cmpxchg_acquire
-/**
- * arch_atomic64_try_cmpxchg_acquire - Atomic try_cmpxchg with acquire ordering
- * @v: pointer of type atomic64_t
- * @old: desired old value to match
- * @new: new value to put in
- *
- * Atomically compares @new to *@v, and if equal,
- * stores @new to *@v, providing acquire ordering.
- * Returns @true if the cmpxchg operation succeeded,
- * and false otherwise.  Either way, stores the old
- * value of *@v to *@old.
- */
+// Fallback acquire omitting duplicate arch_atomic64_try_cmpxchg_acquire() kernel-doc header.
 static __always_inline bool
 arch_atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
 {
@@ -3583,18 +3329,7 @@  arch_atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
 #endif
 
 #ifndef arch_atomic64_try_cmpxchg_release
-/**
- * arch_atomic64_try_cmpxchg_release - Atomic try_cmpxchg with release ordering
- * @v: pointer of type atomic64_t
- * @old: desired old value to match
- * @new: new value to put in
- *
- * Atomically compares @new to *@v, and if equal,
- * stores @new to *@v, providing release ordering.
- * Returns @true if the cmpxchg operation succeeded,
- * and false otherwise.  Either way, stores the old
- * value of *@v to *@old.
- */
+// Fallback release omitting duplicate arch_atomic64_try_cmpxchg_release() kernel-doc header.
 static __always_inline bool
 arch_atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
 {
@@ -3605,18 +3340,7 @@  arch_atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
 #endif
 
 #ifndef arch_atomic64_try_cmpxchg
-/**
- * arch_atomic64_try_cmpxchg - Atomic try_cmpxchg with full ordering
- * @v: pointer of type atomic64_t
- * @old: desired old value to match
- * @new: new value to put in
- *
- * Atomically compares @new to *@v, and if equal,
- * stores @new to *@v, providing full ordering.
- * Returns @true if the cmpxchg operation succeeded,
- * and false otherwise.  Either way, stores the old
- * value of *@v to *@old.
- */
+// Fallback fence omitting duplicate arch_atomic64_try_cmpxchg() kernel-doc header.
 static __always_inline bool
 arch_atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new)
 {
@@ -3761,15 +3485,7 @@  arch_atomic64_add_negative_relaxed(s64 i, atomic64_t *v)
 #else /* arch_atomic64_add_negative_relaxed */
 
 #ifndef arch_atomic64_add_negative_acquire
-/**
- * arch_atomic64_add_negative_acquire - Atomic add_negative with acquire ordering
- * @i: value to add
- * @v: pointer of type atomic64_t
- *
- * Atomically add @i with @v using acquire ordering.
- * Return @true if the result is negative, or @false when
- * the result is greater than or equal to zero.
- */
+// Fallback acquire omitting duplicate arch_atomic64_add_negative_acquire() kernel-doc header.
 static __always_inline bool
 arch_atomic64_add_negative_acquire(s64 i, atomic64_t *v)
 {
@@ -3781,15 +3497,7 @@  arch_atomic64_add_negative_acquire(s64 i, atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_add_negative_release
-/**
- * arch_atomic64_add_negative_release - Atomic add_negative with release ordering
- * @i: value to add
- * @v: pointer of type atomic64_t
- *
- * Atomically add @i with @v using release ordering.
- * Return @true if the result is negative, or @false when
- * the result is greater than or equal to zero.
- */
+// Fallback release omitting duplicate arch_atomic64_add_negative_release() kernel-doc header.
 static __always_inline bool
 arch_atomic64_add_negative_release(s64 i, atomic64_t *v)
 {
@@ -3800,15 +3508,7 @@  arch_atomic64_add_negative_release(s64 i, atomic64_t *v)
 #endif
 
 #ifndef arch_atomic64_add_negative
-/**
- * arch_atomic64_add_negative - Atomic add_negative with full ordering
- * @i: value to add
- * @v: pointer of type atomic64_t
- *
- * Atomically add @i with @v using full ordering.
- * Return @true if the result is negative, or @false when
- * the result is greater than or equal to zero.
- */
+// Fallback fence omitting duplicate arch_atomic64_add_negative() kernel-doc header.
 static __always_inline bool
 arch_atomic64_add_negative(s64 i, atomic64_t *v)
 {
@@ -3958,4 +3658,4 @@  arch_atomic64_dec_if_positive(atomic64_t *v)
 #endif
 
 #endif /* _LINUX_ATOMIC_FALLBACK_H */
-// 7c2c97cd48cf9c672efc44b9fed5a37b8970dde4
+// 9bf9febc5288ed9539d1b3cfbbc6e36743b74c3b
diff --git a/scripts/atomic/chkdup.sh b/scripts/atomic/chkdup.sh
new file mode 100644
index 000000000000..04bb4f5c5c34
--- /dev/null
+++ b/scripts/atomic/chkdup.sh
@@ -0,0 +1,27 @@ 
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Check to see if the specified atomic is already in use.  This is
+# done by keeping filenames in the temporary directory specified by the
+# environment variable T.
+#
+# Usage:
+#	chkdup.sh name fallback
+#
+# The "name" argument is the name of the function to be generated, and
+# the "fallback" argument is the name of the fallback script that is
+# doing the generation.
+#
+# If the function is a duplicate, output a comment saying so and
+# exit with non-zero (error) status.  Otherwise exit successfully
+#
+# If the function is a duplicate, output a comment saying so and
+# exit with non-zero (error) status.  Otherwise exit successfully.
+
+if test -f ${T}/${1}
+then
+	echo // Fallback ${2} omitting duplicate "${1}()" kernel-doc header.
+	exit 1
+fi
+touch ${T}/${1}
+exit 0
diff --git a/scripts/atomic/fallbacks/acquire b/scripts/atomic/fallbacks/acquire
index 08fc6c30a9ef..a349935ac7fe 100755
--- a/scripts/atomic/fallbacks/acquire
+++ b/scripts/atomic/fallbacks/acquire
@@ -1,5 +1,8 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}${name}${sfx}_acquire acquire
+then
 acqrel=acquire
 . ${ATOMICDIR}/acqrel.sh
+fi
 cat << EOF
 static __always_inline ${ret}
 arch_${atomic}_${pfx}${name}${sfx}_acquire(${params})
diff --git a/scripts/atomic/fallbacks/add_negative b/scripts/atomic/fallbacks/add_negative
index c032e8bec6e2..b105fdfe8fd1 100755
--- a/scripts/atomic/fallbacks/add_negative
+++ b/scripts/atomic/fallbacks/add_negative
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_add_negative${order} add_negative
+then
 cat <<EOF
 /**
  * arch_${atomic}_add_negative${order} - Add and test if negative
@@ -7,6 +9,9 @@  cat <<EOF
  * Atomically adds @i to @v and returns @true if the result is negative,
  * or @false when the result is greater than or equal to zero.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline bool
 arch_${atomic}_add_negative${order}(${int} i, ${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/add_unless b/scripts/atomic/fallbacks/add_unless
index 650fee935aed..d72d382e3757 100755
--- a/scripts/atomic/fallbacks/add_unless
+++ b/scripts/atomic/fallbacks/add_unless
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_add_unless add_unless
+then
 cat << EOF
 /**
  * arch_${atomic}_add_unless - add unless the number is already a given value
@@ -8,6 +10,9 @@  cat << EOF
  * Atomically adds @a to @v, if @v was not already @u.
  * Returns @true if the addition was done.
  */
+EOF
+fi
+cat << EOF
 static __always_inline bool
 arch_${atomic}_add_unless(${atomic}_t *v, ${int} a, ${int} u)
 {
diff --git a/scripts/atomic/fallbacks/andnot b/scripts/atomic/fallbacks/andnot
index 9fbc0ce75a7c..57b2a187374a 100755
--- a/scripts/atomic/fallbacks/andnot
+++ b/scripts/atomic/fallbacks/andnot
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}andnot${sfx}${order} andnot
+then
 cat <<EOF
 /**
  * arch_${atomic}_${pfx}andnot${sfx}${order} - Atomic and-not
@@ -7,6 +9,9 @@  cat <<EOF
  * Atomically and-not @i with @v using ${docbook_order} ordering.
  * returning ${docbook_oldnew} value.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline ${ret}
 arch_${atomic}_${pfx}andnot${sfx}${order}(${int} i, ${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/dec b/scripts/atomic/fallbacks/dec
index e99c8edd36a3..e44d3eb96d2b 100755
--- a/scripts/atomic/fallbacks/dec
+++ b/scripts/atomic/fallbacks/dec
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}dec${sfx}${order} dec
+then
 cat <<EOF
 /**
  * arch_${atomic}_${pfx}dec${sfx}${order} - Atomic decrement
@@ -6,6 +8,9 @@  cat <<EOF
  * Atomically decrement @v with ${docbook_order} ordering,
  * returning ${docbook_oldnew} value.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline ${ret}
 arch_${atomic}_${pfx}dec${sfx}${order}(${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/dec_and_test b/scripts/atomic/fallbacks/dec_and_test
index 3720896b1afc..94f5a6d4827c 100755
--- a/scripts/atomic/fallbacks/dec_and_test
+++ b/scripts/atomic/fallbacks/dec_and_test
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_dec_and_test dec_and_test
+then
 cat <<EOF
 /**
  * arch_${atomic}_dec_and_test - decrement and test
@@ -7,6 +9,9 @@  cat <<EOF
  * returns @true if the result is 0, or @false for all other
  * cases.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline bool
 arch_${atomic}_dec_and_test(${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/dec_if_positive b/scripts/atomic/fallbacks/dec_if_positive
index dedbdbc1487d..e27eb71dd1b2 100755
--- a/scripts/atomic/fallbacks/dec_if_positive
+++ b/scripts/atomic/fallbacks/dec_if_positive
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_dec_if_positive dec_if_positive
+then
 cat <<EOF
 /**
  * arch_${atomic}_dec_if_positive - Atomic decrement if old value is positive
@@ -9,6 +11,9 @@  cat <<EOF
  * there @v will not be decremented, but -4 will be returned.  As a result,
  * if the return value is non-negative, then the value was in fact decremented.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline ${ret}
 arch_${atomic}_dec_if_positive(${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/dec_unless_positive b/scripts/atomic/fallbacks/dec_unless_positive
index c3d01d201c63..ee00fffc5f11 100755
--- a/scripts/atomic/fallbacks/dec_unless_positive
+++ b/scripts/atomic/fallbacks/dec_unless_positive
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_dec_unless_positive dec_unless_positive
+then
 cat <<EOF
 /**
  * arch_${atomic}_dec_unless_positive - Atomic decrement if old value is non-positive
@@ -7,6 +9,9 @@  cat <<EOF
  * than or equal to zero.  Return @true if the decrement happened and
  * @false otherwise.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline bool
 arch_${atomic}_dec_unless_positive(${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/fence b/scripts/atomic/fallbacks/fence
index 975855dfba25..f4901343cd2b 100755
--- a/scripts/atomic/fallbacks/fence
+++ b/scripts/atomic/fallbacks/fence
@@ -1,5 +1,8 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}${name}${sfx} fence
+then
 acqrel=full
 . ${ATOMICDIR}/acqrel.sh
+fi
 cat <<EOF
 static __always_inline ${ret}
 arch_${atomic}_${pfx}${name}${sfx}(${params})
diff --git a/scripts/atomic/fallbacks/fetch_add_unless b/scripts/atomic/fallbacks/fetch_add_unless
index a1692df0d514..ec583d340785 100755
--- a/scripts/atomic/fallbacks/fetch_add_unless
+++ b/scripts/atomic/fallbacks/fetch_add_unless
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_fetch_add_unless fetch_add_unless
+then
 cat << EOF
 /**
  * arch_${atomic}_fetch_add_unless - add unless the number is already a given value
@@ -8,6 +10,9 @@  cat << EOF
  * Atomically adds @a to @v, so long as @v was not already @u.
  * Returns original value of @v.
  */
+EOF
+fi
+cat << EOF
 static __always_inline ${int}
 arch_${atomic}_fetch_add_unless(${atomic}_t *v, ${int} a, ${int} u)
 {
diff --git a/scripts/atomic/fallbacks/inc b/scripts/atomic/fallbacks/inc
index 3f2c0730cd0c..bb1d5ea6846c 100755
--- a/scripts/atomic/fallbacks/inc
+++ b/scripts/atomic/fallbacks/inc
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}inc${sfx}${order} inc
+then
 cat <<EOF
 /**
  * arch_${atomic}_${pfx}inc${sfx}${order} - Atomic increment
@@ -6,6 +8,9 @@  cat <<EOF
  * Atomically increment @v with ${docbook_order} ordering,
  * returning ${docbook_oldnew} value.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline ${ret}
 arch_${atomic}_${pfx}inc${sfx}${order}(${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/inc_and_test b/scripts/atomic/fallbacks/inc_and_test
index cc3ac1dde508..dd74f6a5ca4a 100755
--- a/scripts/atomic/fallbacks/inc_and_test
+++ b/scripts/atomic/fallbacks/inc_and_test
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_inc_and_test inc_and_test
+then
 cat <<EOF
 /**
  * arch_${atomic}_inc_and_test - increment and test
@@ -7,6 +9,9 @@  cat <<EOF
  * and returns @true if the result is zero, or @false for all
  * other cases.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline bool
 arch_${atomic}_inc_and_test(${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/inc_not_zero b/scripts/atomic/fallbacks/inc_not_zero
index 891fa3c057f6..38e2c13dab62 100755
--- a/scripts/atomic/fallbacks/inc_not_zero
+++ b/scripts/atomic/fallbacks/inc_not_zero
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_inc_not_zero inc_not_zero
+then
 cat <<EOF
 /**
  * arch_${atomic}_inc_not_zero - increment unless the number is zero
@@ -6,6 +8,9 @@  cat <<EOF
  * Atomically increments @v by 1, if @v is non-zero.
  * Returns @true if the increment was done.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline bool
 arch_${atomic}_inc_not_zero(${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/inc_unless_negative b/scripts/atomic/fallbacks/inc_unless_negative
index 98830b0dcdb1..2dc853c4e5b9 100755
--- a/scripts/atomic/fallbacks/inc_unless_negative
+++ b/scripts/atomic/fallbacks/inc_unless_negative
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_inc_unless_negative inc_unless_negative
+then
 cat <<EOF
 /**
  * arch_${atomic}_inc_unless_negative - Atomic increment if old value is non-negative
@@ -7,6 +9,9 @@  cat <<EOF
  * than or equal to zero.  Return @true if the increment happened and
  * @false otherwise.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline bool
 arch_${atomic}_inc_unless_negative(${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/read_acquire b/scripts/atomic/fallbacks/read_acquire
index 779f40c07018..680cd43080cb 100755
--- a/scripts/atomic/fallbacks/read_acquire
+++ b/scripts/atomic/fallbacks/read_acquire
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_read_acquire read_acquire
+then
 cat <<EOF
 /**
  * arch_${atomic}_read_acquire - Atomic load acquire
@@ -6,6 +8,9 @@  cat <<EOF
  * Atomically load from *@v with acquire ordering, returning the value
  * loaded.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline ${ret}
 arch_${atomic}_read_acquire(const ${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/release b/scripts/atomic/fallbacks/release
index bce3a1cbd497..a1604df66ece 100755
--- a/scripts/atomic/fallbacks/release
+++ b/scripts/atomic/fallbacks/release
@@ -1,5 +1,8 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_${pfx}${name}${sfx}_release release
+then
 acqrel=release
 . ${ATOMICDIR}/acqrel.sh
+fi
 cat <<EOF
 static __always_inline ${ret}
 arch_${atomic}_${pfx}${name}${sfx}_release(${params})
diff --git a/scripts/atomic/fallbacks/set_release b/scripts/atomic/fallbacks/set_release
index 46effb6203e5..2a65d3b29f4b 100755
--- a/scripts/atomic/fallbacks/set_release
+++ b/scripts/atomic/fallbacks/set_release
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_set_release set_release
+then
 cat <<EOF
 /**
  * arch_${atomic}_set_release - Atomic store release
@@ -6,6 +8,9 @@  cat <<EOF
  *
  * Atomically store @i into *@v with release ordering.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline void
 arch_${atomic}_set_release(${atomic}_t *v, ${int} i)
 {
diff --git a/scripts/atomic/fallbacks/sub_and_test b/scripts/atomic/fallbacks/sub_and_test
index 204282e260ea..0397b0e92192 100755
--- a/scripts/atomic/fallbacks/sub_and_test
+++ b/scripts/atomic/fallbacks/sub_and_test
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_sub_and_test sub_and_test
+then
 cat <<EOF
 /**
  * arch_${atomic}_sub_and_test - subtract value from variable and test result
@@ -8,6 +10,9 @@  cat <<EOF
  * @true if the result is zero, or @false for all
  * other cases.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline bool
 arch_${atomic}_sub_and_test(${int} i, ${atomic}_t *v)
 {
diff --git a/scripts/atomic/fallbacks/try_cmpxchg b/scripts/atomic/fallbacks/try_cmpxchg
index baf7412f9bf4..e08c5962dd83 100755
--- a/scripts/atomic/fallbacks/try_cmpxchg
+++ b/scripts/atomic/fallbacks/try_cmpxchg
@@ -1,3 +1,5 @@ 
+if /bin/sh ${ATOMICDIR}/chkdup.sh arch_${atomic}_try_cmpxchg${order} try_cmpxchg
+then
 cat <<EOF
 /**
  * arch_${atomic}_try_cmpxchg${order} - Atomic cmpxchg with bool return value
@@ -9,6 +11,9 @@  cat <<EOF
  * providing ${docbook_order} ordering.
  * Returns @true if the cmpxchg operation succeeded, and false otherwise.
  */
+EOF
+fi
+cat <<EOF
 static __always_inline bool
 arch_${atomic}_try_cmpxchg${order}(${atomic}_t *v, ${int} *old, ${int} new)
 {
diff --git a/scripts/atomic/gen-atomics.sh b/scripts/atomic/gen-atomics.sh
index 5b98a8307693..69bf3754df5a 100755
--- a/scripts/atomic/gen-atomics.sh
+++ b/scripts/atomic/gen-atomics.sh
@@ -3,6 +3,10 @@ 
 #
 # Generate atomic headers
 
+T="`mktemp -d ${TMPDIR-/tmp}/gen-atomics.sh.XXXXXX`"
+trap 'rm -rf $T' 0
+export T
+
 ATOMICDIR=$(dirname $0)
 ATOMICTBL=${ATOMICDIR}/atomics.tbl
 LINUXDIR=${ATOMICDIR}/../..