locking/atomic: scripts: simplify raw_atomic*() definitionsCurrently each ordering variant has several potential definitions,with a mixture of preprocessor and C definitions, including severalcop
locking/atomic: scripts: simplify raw_atomic*() definitionsCurrently each ordering variant has several potential definitions,with a mixture of preprocessor and C definitions, including severalcopies of its C prototype, e.g.| #if defined(arch_atomic_fetch_andnot_acquire)| #define raw_atomic_fetch_andnot_acquire arch_atomic_fetch_andnot_acquire| #elif defined(arch_atomic_fetch_andnot_relaxed)| static __always_inline int| raw_atomic_fetch_andnot_acquire(int i, atomic_t *v)| {| int ret = arch_atomic_fetch_andnot_relaxed(i, v);| __atomic_acquire_fence();| return ret;| }| #elif defined(arch_atomic_fetch_andnot)| #define raw_atomic_fetch_andnot_acquire arch_atomic_fetch_andnot| #else| static __always_inline int| raw_atomic_fetch_andnot_acquire(int i, atomic_t *v)| {| return raw_atomic_fetch_and_acquire(~i, v);| }| #endifMake this a bit simpler by defining the C prototype once, and writingthe various potential definitions as plain C code guarded by ifdeffery.For example, the above becomes:| static __always_inline int| raw_atomic_fetch_andnot_acquire(int i, atomic_t *v)| {| #if defined(arch_atomic_fetch_andnot_acquire)| return arch_atomic_fetch_andnot_acquire(i, v);| #elif defined(arch_atomic_fetch_andnot_relaxed)| int ret = arch_atomic_fetch_andnot_relaxed(i, v);| __atomic_acquire_fence();| return ret;| #elif defined(arch_atomic_fetch_andnot)| return arch_atomic_fetch_andnot(i, v);| #else| return raw_atomic_fetch_and_acquire(~i, v);| #endif| }Which is far easier to read. As we now always have a single copy of theC prototype wrapping all the potential definitions, we now have anobvious single location for kerneldoc comments.At the same time, the fallbacks for raw_atomic*_xhcg() are made to use'new' rather than 'i' as the name of the new value. This is what theexisting fallback template used, and is more consistent with theraw_atomic{_try,}cmpxchg() fallbacks.There should be no functional change as a result of this patch.Signed-off-by: Mark Rutland <mark.rutland@arm.com>Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>Reviewed-by: Kees Cook <keescook@chromium.org>Link: https://lore.kernel.org/r/20230605070124.3741859-24-mark.rutland@arm.com
show more ...
locking/atomic: scripts: restructure fallback ifdefferyCurrently the various ordering variants of an atomic operation aredefined in groups of full/acquire/release/relaxed ordering variants withso
locking/atomic: scripts: restructure fallback ifdefferyCurrently the various ordering variants of an atomic operation aredefined in groups of full/acquire/release/relaxed ordering variants withsome shared ifdeffery and several potential definitions of each orderingvariant in different branches of the shared ifdeffery.As an ordering variant can have several potential definitions downdifferent branches of the shared ifdeffery, it can be painful for ahuman to find a relevant definition, and we don't have a good locationto place anything common to all definitions of an ordering variant (e.g.kerneldoc).Historically the grouping of full/acquire/release/relaxed orderingvariants was necessary as we filled in the missing atomics in the samenamespace as the architecture used. It would be easy to accidentallydefine one ordering fallback in terms of another ordering fallback withredundant barriers, and avoiding that would otherwise require a lot ofbaroque ifdeffery.With recent changes we no longer need to fill in the missing atomics inthe arch_atomic*_<op>() namespace, and only need to fill in theraw_atomic*_<op>() namespace. Due to this, there's no risk of anamespace collision, and we can define each raw_atomic*_<op> orderingvariant with its own ifdeffery checking for the arch_atomic*_<op>ordering variants.Restructure the fallbacks in this way, with each ordering variant havingits own ifdeffery of the form:| #if defined(arch_atomic_fetch_andnot_acquire)| #define raw_atomic_fetch_andnot_acquire arch_atomic_fetch_andnot_acquire| #elif defined(arch_atomic_fetch_andnot_relaxed)| static __always_inline int| raw_atomic_fetch_andnot_acquire(int i, atomic_t *v)| {| int ret = arch_atomic_fetch_andnot_relaxed(i, v);| __atomic_acquire_fence();| return ret;| }| #elif defined(arch_atomic_fetch_andnot)| #define raw_atomic_fetch_andnot_acquire arch_atomic_fetch_andnot| #else| static __always_inline int| raw_atomic_fetch_andnot_acquire(int i, atomic_t *v)| {| return raw_atomic_fetch_and_acquire(~i, v);| }| #endifNote that where there's no relevant arch_atomic*_<op>() orderingvariant, we'll define the operation in terms of a distinctraw_atomic*_<otherop>(), as this itself might have been filled in with afallback.As we now generate the raw_atomic*_<op>() implementations directly, weno longer need the trivial wrappers, so they are removed.This makes the ifdeffery easier to follow, and will allow for furtherimprovements in subsequent patches.There should be no functional change as a result of this patch.Signed-off-by: Mark Rutland <mark.rutland@arm.com>Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>Reviewed-by: Kees Cook <keescook@chromium.org>Link: https://lore.kernel.org/r/20230605070124.3741859-21-mark.rutland@arm.com
locking/atomic: make atomic*_{cmp,}xchg optionalMost architectures define the atomic/atomic64 xchg and cmpxchgoperations in terms of arch_xchg and arch_cmpxchg respectfully.Add fallbacks for the
locking/atomic: make atomic*_{cmp,}xchg optionalMost architectures define the atomic/atomic64 xchg and cmpxchgoperations in terms of arch_xchg and arch_cmpxchg respectfully.Add fallbacks for these cases and remove the trivial cases from archcode. On some architectures the existing definitions are kept as theseare used to build other arch_atomic*() operations.Signed-off-by: Mark Rutland <mark.rutland@arm.com>Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>Reviewed-by: Kees Cook <keescook@chromium.org>Link: https://lore.kernel.org/r/20230605070124.3741859-5-mark.rutland@arm.com
locking/atomic: remove fallback commentsCurrently a subset of the fallback templates have kerneldoc comments,resulting in a haphazard set of generated kerneldoc comments as onlysome operations ha
locking/atomic: remove fallback commentsCurrently a subset of the fallback templates have kerneldoc comments,resulting in a haphazard set of generated kerneldoc comments as onlysome operations have fallback templates to begin with.We'd like to generate more consistent kerneldoc comments, and to do sowe'll need to restructure the way the fallback code is generated.To minimize churn and to make it easier to restructure the fallbackcode, this patch removes the existing kerneldoc comments from thefallback templates. We can add new kerneldoc comments in subsequentpatches.There should be no functional change as a result of this patch.Signed-off-by: Mark Rutland <mark.rutland@arm.com>Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>Reviewed-by: Kees Cook <keescook@chromium.org>Link: https://lore.kernel.org/r/20230605070124.3741859-3-mark.rutland@arm.com
atomics: Provide atomic_add_negative() variantsatomic_add_negative() does not provide the relaxed/acquire/releasevariants.Provide them in preparation for a new scalable reference count algorithm
atomics: Provide atomic_add_negative() variantsatomic_add_negative() does not provide the relaxed/acquire/releasevariants.Provide them in preparation for a new scalable reference count algorithm.Signed-off-by: Thomas Gleixner <tglx@linutronix.de>Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>Acked-by: Mark Rutland <mark.rutland@arm.com>Link: https://lore.kernel.org/r/20230323102800.101763813@linutronix.de
atomics: Fix atomic64_{read_acquire,set_release} fallbacksArnd reports that on 32-bit architectures, the fallbacks foratomic64_read_acquire() and atomic64_set_release() are broken as theyuse smp_
atomics: Fix atomic64_{read_acquire,set_release} fallbacksArnd reports that on 32-bit architectures, the fallbacks foratomic64_read_acquire() and atomic64_set_release() are broken as theyuse smp_load_acquire() and smp_store_release() respectively, which donot work on types larger than the native word size.Since those contain compiletime_assert_atomic_type(), any attempt to usethose fallbacks will result in a build-time error. e.g. with thefollowing added to arch/arm/kernel/setup.c:| void test_atomic64(atomic64_t *v)| {| atomic64_set_release(v, 5);| atomic64_read_acquire(v);| }The compiler will complain as follows:| In file included from <command-line>:| In function 'arch_atomic64_set_release',| inlined from 'test_atomic64' at ./include/linux/atomic/atomic-instrumented.h:669:2:| ././include/linux/compiler_types.h:346:38: error: call to '__compiletime_assert_9' declared with attribute error: Need native word sized stores/loads for atomicity.| 346 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)| | ^| ././include/linux/compiler_types.h:327:4: note: in definition of macro '__compiletime_assert'| 327 | prefix ## suffix(); \| | ^~~~~~| ././include/linux/compiler_types.h:346:2: note: in expansion of macro '_compiletime_assert'| 346 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)| | ^~~~~~~~~~~~~~~~~~~| ././include/linux/compiler_types.h:349:2: note: in expansion of macro 'compiletime_assert'| 349 | compiletime_assert(__native_word(t), \| | ^~~~~~~~~~~~~~~~~~| ./include/asm-generic/barrier.h:133:2: note: in expansion of macro 'compiletime_assert_atomic_type'| 133 | compiletime_assert_atomic_type(*p); \| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| ./include/asm-generic/barrier.h:164:55: note: in expansion of macro '__smp_store_release'| 164 | #define smp_store_release(p, v) do { kcsan_release(); __smp_store_release(p, v); } while (0)| | ^~~~~~~~~~~~~~~~~~~| ./include/linux/atomic/atomic-arch-fallback.h:1270:2: note: in expansion of macro 'smp_store_release'| 1270 | smp_store_release(&(v)->counter, i);| | ^~~~~~~~~~~~~~~~~| make[2]: *** [scripts/Makefile.build:288: arch/arm/kernel/setup.o] Error 1| make[1]: *** [scripts/Makefile.build:550: arch/arm/kernel] Error 2| make: *** [Makefile:1831: arch/arm] Error 2Fix this by only using smp_load_acquire() and smp_store_release() fornative atomic types, and otherwise falling back to the regular barriersnecessary for acquire/release semantics, as we do in the more genericacquire and release fallbacks.Since the fallback templates are used to generate the atomic64_*() andatomic_*() operations, the __native_word() check is added to both. Forthe atomic_*() operations, which are always 32-bit, the __native_word()check is redundant but not harmful, as it is always true.For the example above this works as expected on 32-bit, e.g. for armmulti_v7_defconfig:| <test_atomic64>:| push {r4, r5}| dmb ish| pldw [r0]| mov r2, #5| mov r3, #0| ldrexd r4, [r0]| strexd r4, r2, [r0]| teq r4, #0| bne 484 <test_atomic64+0x14>| ldrexd r2, [r0]| dmb ish| pop {r4, r5}| bx lr... and also on 64-bit, e.g. for arm64 defconfig:| <test_atomic64>:| bti c| paciasp| mov x1, #0x5| stlr x1, [x0]| ldar x0, [x0]| autiasp| retReported-by: Arnd Bergmann <arnd@arndb.de>Signed-off-by: Mark Rutland <mark.rutland@arm.com>Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>Reviewed-by: Ard Biesheuvel <ardb@kernel.org>Reviewed-by: Boqun Feng <boqun.feng@gmail.com>Link: https://lore.kernel.org/r/20220207101943.439825-1-mark.rutland@arm.com
locking/atomic: remove ARCH_ATOMIC remanantsNow that gen-atomic-fallback.sh is only used to generate the arch_*fallbacks, we don't need to also generate the non-arch_* forms, and canremovethe inf
locking/atomic: remove ARCH_ATOMIC remanantsNow that gen-atomic-fallback.sh is only used to generate the arch_*fallbacks, we don't need to also generate the non-arch_* forms, and canremovethe infrastructure this needed.There is no change to any of the generated headers as a result of thispatch.Signed-off-by: Mark Rutland <mark.rutland@arm.com>Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>Link: https://lore.kernel.org/r/20210713105253.7615-3-mark.rutland@arm.com
locking/atomics: Flip fallbacks and instrumentationCurrently instrumentation of atomic primitives is done at the architecturelevel, while composites or fallbacks are provided at the generic level.
locking/atomics: Flip fallbacks and instrumentationCurrently instrumentation of atomic primitives is done at the architecturelevel, while composites or fallbacks are provided at the generic level.The result is that there are no uninstrumented variants of thefallbacks. Since there is now need of such variants to isolate text pokefrom any form of instrumentation invert this ordering.Doing this means moving the instrumentation into the generic code aswell as having (for now) two variants of the fallbacks.Notes: - the various *cond_read* primitives are not proper fallbacks and got moved into linux/atomic.c. No arch_ variants are generated because the base primitives smp_cond_load*() are instrumented. - once all architectures are moved over to arch_atomic_ one of the fallback variants can be removed and some 2300 lines reclaimed. - atomic_{read,set}*() are no longer double-instrumentedReported-by: Thomas Gleixner <tglx@linutronix.de>Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>Signed-off-by: Thomas Gleixner <tglx@linutronix.de>Acked-by: Mark Rutland <mark.rutland@arm.com>Link: https://lkml.kernel.org/r/20200505134058.769149955@linutronix.de
asm-generic/atomic: Use __always_inline for fallback wrappersUse __always_inline for atomic fallback wrappers. When building for size(CC_OPTIMIZE_FOR_SIZE), some compilers appear to be less inclin
asm-generic/atomic: Use __always_inline for fallback wrappersUse __always_inline for atomic fallback wrappers. When building for size(CC_OPTIMIZE_FOR_SIZE), some compilers appear to be less inclined toinline even relatively small static inline functions that are assumed tobe inlinable such as atomic ops. This can cause problems, for example inUACCESS regions.While the fallback wrappers aren't pure wrappers, they are trivialnonetheless, and the function they wrap should determine the finalinlining policy.For x86 tinyconfig we observe:- vmlinux baseline: 1315988- vmlinux with patch: 1315928 (-60 bytes)[ tglx: Cherry-picked from KCSAN ]Suggested-by: Mark Rutland <mark.rutland@arm.com>Signed-off-by: Marco Elver <elver@google.com>Acked-by: Mark Rutland <mark.rutland@arm.com>Signed-off-by: Paul E. McKenney <paulmck@kernel.org>Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
locking/atomics: Fix scripts/atomic/ script permissionsMark all these scripts executable.Cc: Mark Rutland <mark.rutland@arm.com>Cc: Peter Zijlstra (Intel) <peterz@infradead.org>Cc: Will Deacon
locking/atomics: Fix scripts/atomic/ script permissionsMark all these scripts executable.Cc: Mark Rutland <mark.rutland@arm.com>Cc: Peter Zijlstra (Intel) <peterz@infradead.org>Cc: Will Deacon <will.deacon@arm.com>Cc: linux-arm-kernel@lists.infradead.orgCc: Catalin Marinas <catalin.marinas@arm.com>Cc: linuxdrivers@attotech.comCc: dvyukov@google.comCc: boqun.feng@gmail.comCc: arnd@arndb.deCc: aryabinin@virtuozzo.comCc: glider@google.comCc: linux-kernel@vger.kernel.orgSigned-off-by: Ingo Molnar <mingo@kernel.org>
locking/atomics: Add common header generation filesTo minimize repetition, to allow for future rework, and to ensureregularity of the various atomic APIs, we'd like to automaticallygenerate (the
locking/atomics: Add common header generation filesTo minimize repetition, to allow for future rework, and to ensureregularity of the various atomic APIs, we'd like to automaticallygenerate (the bulk of) a number of headers related to atomics.This patch adds the infrastructure to do so, leaving actual conversionof headers to subsequent patches. This infrastructure consists of:* atomics.tbl - a table describing the functions in the atomics API, with names, prototypes, and metadata describing the variants that exist (e.g fetch/return, acquire/release/relaxed). Note that the return type is dependent on the particular variant.* atomic-tbl.sh - a library of routines useful for dealing with atomics.tbl (e.g. querying which variants exist, or generating argument/parameter lists for a given function variant).* gen-atomic-fallback.sh - a script which generates a header of fallbacks, covering cases where architecture omit certain functions (e.g. omitting relaxed variants).* gen-atomic-long.sh - a script which generates wrappers providing the atomic_long API atomic of the relevant atomic or atomic64 API, ensuring the APIs are consistent.* gen-atomic-instrumented.sh - a script which generates atomic* wrappers atop of arch_atomic* functions, with automatically generated KASAN instrumentation.* fallbacks/* - a set of fallback implementations for atomics, which should be used when no implementation of a given atomic is provided. These are used by gen-atomic-fallback.sh to generate fallbacks, and these are also used by other scripts to determine the set of optional atomics (as required to generate preprocessor guards correctly). Fallbacks may use the following variables: ${atomic} atomic prefix: atomic/atomic64/atomic_long, which can be used to derive the atomic type, and to prefix functions ${int} integer type: int/s64/long ${pfx} variant prefix, e.g. fetch_ ${name} base function name, e.g. add ${sfx} variant suffix, e.g. _return ${order} order suffix, e.g. _relaxed ${atomicname} full name, e.g. atomic64_fetch_add_relaxed ${ret} return type of the function, e.g. void ${retstmt} a return statement (with a trailing space), unless the variant returns void ${params} parameter list for the function declaration, e.g. "int i, atomic_t *v" ${args} argument list for invoking the function, e.g. "i, v" ... for clarity, ${ret}, ${retstmt}, ${params}, and ${args} are open-coded for fallbacks where these do not vary, or are critical to understanding the logic of the fallback.The MAINTAINERS entry for the atomic infrastructure is updated to coverthe new scripts.There should be no functional change as a result of this patch.Signed-off-by: Mark Rutland <mark.rutland@arm.com>Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>Cc: linux-arm-kernel@lists.infradead.orgCc: catalin.marinas@arm.comCc: Will Deacon <will.deacon@arm.com>Cc: linuxdrivers@attotech.comCc: dvyukov@google.comCc: Boqun Feng <boqun.feng@gmail.com>Cc: arnd@arndb.deCc: aryabinin@virtuozzo.comCc: glider@google.comLink: http://lkml.kernel.org/r/20180904104830.2975-2-mark.rutland@arm.comSigned-off-by: Ingo Molnar <mingo@kernel.org>