Align atomic storage
Subsystems (6)
v5 cover Align atomic storage
This series adds the __aligned attribute to atomic_t and atomic64_t definitions in include/linux and include/asm-generic (respectively) to get natural alignment of both types on csky, m68k, microblaze, nios2, openrisc and sh.
This series also adds Kconfig options to enable a new run-time warning to help reveal misaligned atomic accesses on platforms which don't trap that.
The performance impact is expected to vary across platforms and workloads. The measurements I made on m68k show that some workloads run faster and others slower.
---
Changed since v4:
- Dropped parisc header file patch as it's been merged already.
- Submitted as PATCH instead of RFC.
Changed since v3:
- Rebased on v6.17.
- New patch to resolve header dependency issue on parisc.
- Dropped documentation patch.
Changed since v2:
- Specify natural alignment for atomic64_t.
- CONFIG_DEBUG_ATOMIC checks for natural alignment again.
- New patch to add weakened alignment check.
- New patch for explicit alignment in BPF header.
---
Finn Thain (3):
bpf: Explicitly align bpf_res_spin_lock
atomic: Specify alignment for atomic_t and atomic64_t
atomic: Add option for weaker alignment check
Peter Zijlstra (1):
atomic: Add alignment check to instrumented atomic operations
include/asm-generic/atomic64.h | 2 +- include/asm-generic/rqspinlock.h | 2 +- include/linux/instrumented.h | 15 +++++++++++++++ include/linux/types.h | 2 +- kernel/bpf/rqspinlock.c | 1 - lib/Kconfig.debug | 18 ++++++++++++++++++ 6 files changed, 36 insertions(+), 4 deletions(-)
Signature · 1 line
2.49.1
PATCH v5 1/4 bpf: Explicitly align bpf_res_spin_lock
Align bpf_res_spin_lock to avoid a BUILD_BUG_ON() when the alignment changes, as it will do on m68k when, in a subsequent patch, the minimum alignment of the atomic_t member of struct rqspinlock gets increased from 2 to 4. Drop the BUILD_BUG_ON() as it becomes redundant.
--- include/asm-generic/rqspinlock.h | 2 +- kernel/bpf/rqspinlock.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
include/asm-generic/rqspinlock.h +1 -1
@@ -28,7 +28,7 @@ struct rqspinlock {*/ struct bpf_res_spin_lock {u32 val; -}; +}__aligned(__alignof__(struct rqspinlock)) ;struct qspinlock ;#ifdef CONFIG_QUEUED_SPINLOCKS
kernel/bpf/rqspinlock.c +0 -1
@@ -692,7 +692,6 @@ __bpf_kfunc int bpf_res_spin_lock(struct bpf_res_spin_lock *lock)int ret;BUILD_BUG_ON (sizeof (rqspinlock_t) !=sizeof (struct bpf_res_spin_lock )); -BUILD_BUG_ON (__alignof__(rqspinlock_t ) != __alignof__(struct bpf_res_spin_lock ));preempt_disable (); ret =res_spin_lock ((rqspinlock_t *)lock);
Signature · 1 line
2.49.1
Re: [PATCH v5 1/4] bpf: Explicitly align bpf_res_spin_lock
Quoted 9 lines · Finn Thain
Align
bpf_res_spin_lockto avoid aBUILD_BUG_ON()when the alignment changes, as it will do on m68k when, in a subsequent patch, the minimum alignment of theatomic_tmember of struct rqspinlock gets increased from 2 to 4. Drop theBUILD_BUG_ON()as it becomes redundant.Cc Geert Uytterhoeven <[email protected]>Signed-off-by Finn Thain <[email protected]>
PATCH v5 2/4 atomic: Specify alignment for atomic_t and atomic64_t
In reply to Finn ThainSome recent commits incorrectly assumed 4-byte alignment of locks. That assumption fails on Linux/m68k (and, interestingly, would have failed on Linux/cris also). The jump label implementation makes a similar alignment assumption.
The expectation that atomic_t and atomic64_t variables will be naturally aligned seems reasonable, as indeed they are on 64-bit architectures. But atomic64_t isn't naturally aligned on csky, m68k, microblaze, nios2, openrisc and sh. Neither atomic_t nor atomic64_t are naturally aligned on m68k.
This patch brings a little uniformity by specifying natural alignment for atomic types. One benefit is that atomic64_t variables do not get split across a page boundary. The cost is that some structs grow which leads to cache misses and wasted memory.
---
Changed since v2:
- Specify natural alignment for atomic64_t.
Changed since v1:
- atomic64_t now gets an __aligned attribute too.
- The 'Fixes' tag has been dropped because Lance sent a different fix for commit e711faaafbe5 ("hung_task: replace blocker_mutex with encoded blocker") that's suitable for -stable.
--- include/asm-generic/atomic64.h | 2 +- include/linux/types.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
include/asm-generic/atomic64.h +1 -1
@@ -10,7 +10,7 @@#include <linux/types.h> typedef struct { -s64 counter; +s64 __aligned(sizeof(s64)) counter; }atomic64_t ;#define ATOMIC64_INIT (i) { (i) }
include/linux/types.h +1 -1
@@ -179,7 +179,7 @@ typedef phys_addr_t resource_size_t;typedef unsigned long irq_hw_number_t ;typedef struct { -int counter; +int __aligned(sizeof(int)) counter; }atomic_t ;#define ATOMIC_INIT (i) { (i) }
Signature · 1 line
2.49.1
Re: [PATCH v5 2/4] atomic: Specify alignment for atomic_t and atomic64_t
Quoted 51 lines · Finn Thain
Some recent commits incorrectly assumed 4-byte alignment of locks. That assumption fails on Linux/m68k (and, interestingly, would have failed on Linux/cris also). The jump label implementation makes a similar alignment assumption.
The expectation that
atomic_tandatomic64_tvariables will be naturally aligned seems reasonable, as indeed they are on 64-bit architectures. Butatomic64_tisn't naturally aligned on csky, m68k, microblaze, nios2, openrisc and sh. Neitheratomic_tnoratomic64_tare naturally aligned on m68k.This patch brings a little uniformity by specifying natural alignment for atomic types. One benefit is that
atomic64_tvariables do not get split across a page boundary. The cost is that some structs grow which leads to cache misses and wasted memory.Cc Guo Ren <[email protected]>Cc Geert Uytterhoeven <[email protected]>Cc Dinh Nguyen <[email protected]>Cc Jonas Bonn <[email protected]>Cc Stefan Kristiansson <[email protected]>Cc Stafford Horne <[email protected]>Cc Yoshinori Sato <[email protected]>Cc Rich Felker <[email protected]>Cc John Paul Adrian Glaubitz <[email protected]>Link https://lore.kernel.org/lkml/CAFr9PX=MYUDGJS2kAvPMkkfvH+0-SwQB_kxE4ea0J_wZ_pk=7w@mail.gmail.com open hereLink https://lore.kernel.org/lkml/CAMuHMdW7Ab13DdGs2acMQcix5ObJK0O2dG_Fxzr8_g58Rc1_0g@mail.gmail.com/ open hereSigned-off-by Finn Thain <[email protected]>---
Changed since v2:
- Specify natural alignment foratomic64_t.
Changed since v1:
-atomic64_tnow gets an__alignedattribute too.
- The 'Fixes' tag has been dropped because Lance sent a different fix for commite711faaafbe5("hung_task: replaceblocker_mutexwith encoded blocker") that's suitable for -stable.--- include/asm-generic/atomic64.h | 2 +- include/linux/types.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)include/asm-generic/atomic64.h +0
-0
include/asm-generic/atomic64.h line 13
Quoted 5 lines
include/asm-generic/atomic64.h +1
-1@@ -10,7 +10,7 @@#include <linux/types.h> typedef struct { - s64 counter; + s64 __aligned(sizeof(s64)) counter;
This alignment is okay for all.
Quoted 19 lines
include/asm-generic/atomic64.h +0
-0} atomic64_t;#define ATOMIC64_INIT (i) { (i) }include/linux/types.h +1
-2@@ -179,7 +179,7 @@ typedef phys_addr_t resource_size_t;typedef unsigned long irq_hw_number_t ;typedef struct { -int counter; +int __aligned(sizeof(int)) counter; }atomic_t ;#define ATOMIC_INIT (i) { (i) } --2.49.1
Signature · 2 lines
Best Regards Guo Ren
Re: [PATCH v5 2/4] atomic: Specify alignment for atomic_t and atomic64_t
In reply to Finn ThainQuoted 11 lines · Finn Thain
Some recent commits incorrectly assumed 4-byte alignment of locks. That assumption fails on Linux/m68k (and, interestingly, would have failed on Linux/cris also). The jump label implementation makes a similar alignment assumption.
The expectation that
atomic_tandatomic64_tvariables will be naturally aligned seems reasonable, as indeed they are on 64-bit architectures. Butatomic64_tisn't naturally aligned on csky, m68k, microblaze, nios2, openrisc and sh. Neitheratomic_tnoratomic64_tare naturally aligned on m68k.
Quoted 4 lines
This patch brings a little uniformity by specifying natural alignment for atomic types. One benefit is that
atomic64_tvariables do not get split across a page boundary. The cost is that some structs grow which leads to cache misses and wasted memory.
PATCH v5 3/4 atomic: Add alignment check to instrumented atomic operations
In reply to Finn ThainFrom: Peter Zijlstra <[email protected]>
Add a Kconfig option for debug builds which logs a warning when an instrumented atomic operation takes place that's misaligned. Some platforms don't trap for this.
---
Changed since v2:
- Always check for natural alignment.
---
Checkpatch.pl says...
ERROR: Missing Signed-off-by: line by nominal patch author 'Peter Zijlstra <[email protected]>'
--- include/linux/instrumented.h | 4 ++++ lib/Kconfig.debug | 10 ++++++++++ 2 files changed, 14 insertions(+)
include/linux/instrumented.h +4 -0
@@ -7,6 +7,7 @@#ifndef _LINUX_INSTRUMENTED_H#define _LINUX_INSTRUMENTED_H +#include <linux/bug.h> #include <linux/compiler.h> #include <linux/kasan-checks.h> #include <linux/kcsan-checks.h>
@@ -67,6 +68,7 @@ static __always_inline void instrument_atomic_read(const volatile void *v, size_ {kasan_check_read (v, size);kcsan_check_atomic_read (v, size); +WARN_ON_ONCE (IS_ENABLED (CONFIG_DEBUG_ATOMIC ) && ((unsigned long )v & (size -1 ))); }/**
@@ -81,6 +83,7 @@ static __always_inline void instrument_atomic_write(const volatile void *v, size {kasan_check_write (v, size);kcsan_check_atomic_write (v, size); +WARN_ON_ONCE (IS_ENABLED (CONFIG_DEBUG_ATOMIC ) && ((unsigned long )v & (size -1 ))); }/**
@@ -95,6 +98,7 @@ static __always_inline void instrument_atomic_read_write(const volatile void *v, {kasan_check_write (v, size);kcsan_check_atomic_read_write (v, size); +WARN_ON_ONCE (IS_ENABLED (CONFIG_DEBUG_ATOMIC ) && ((unsigned long )v & (size -1 ))); }/**
lib/Kconfig.debug +10 -0
@@ -1356,6 +1356,16 @@ config DEBUG_PREEMPT depending on workload as it triggers debugging routines for each this_cpu operation. It should only be used for debugging purposes. +config DEBUG_ATOMIC + bool "Debug atomic variables" + depends on DEBUG_KERNEL + help + If you say Y here then the kernel will add a runtime alignment check + to atomic accesses. Useful for architectures that do not have trap on + mis-aligned access. + + This option has potentially significant overhead. + menu "Lock Debugging (spinlocks, mutexes, etc...)" config LOCK_DEBUGGING_SUPPORT
Signature · 1 line
2.49.1
PATCH v5 4/4 atomic: Add option for weaker alignment check
In reply to Finn ThainAdd a new Kconfig symbol to make CONFIG_DEBUG_ATOMIC more useful on those architectures which do not align dynamic allocations to 8-byte boundaries. Without this, CONFIG_DEBUG_ATOMIC produces excessive WARN splats.
---
Changed since v3:
- Dropped #include <linux/cache.h> to avoid a build failure on arm64.
- Rewrote Kconfig help text to better describe preferred alignment.
- Refactored to avoid line-wrapping and duplication.
--- include/linux/instrumented.h | 17 ++++++++++++++--- lib/Kconfig.debug | 8 ++++++++ 2 files changed, 22 insertions(+), 3 deletions(-)
include/linux/instrumented.h +14 -3
@@ -56,6 +56,17 @@ static __always_inline void instrument_read_write(const volatile void *v, size_tkcsan_check_read_write (v, size); } +static __always_inline void instrument_atomic_check_alignment(const volatile void *v, size_t size) +{ +if (IS_ENABLED (CONFIG_DEBUG_ATOMIC )) { +unsigned int mask = size -1 ; + +if (IS_ENABLED (CONFIG_DEBUG_ATOMIC_LARGEST_ALIGN )) + mask &= sizeof(struct { long x; } __aligned_largest) - 1; +WARN_ON_ONCE ((unsigned long )v & mask); + } +} +/** * instrument_atomic_read - instrument atomic read access * @v: address of access
@@ -68,7 +79,7 @@ static __always_inline void instrument_atomic_read(const volatile void *v, size_ {kasan_check_read (v, size);kcsan_check_atomic_read (v, size); -WARN_ON_ONCE (IS_ENABLED (CONFIG_DEBUG_ATOMIC ) && ((unsigned long )v & (size -1 ))); +instrument_atomic_check_alignment (v, size); }/**
@@ -83,7 +94,7 @@ static __always_inline void instrument_atomic_write(const volatile void *v, size {kasan_check_write (v, size);kcsan_check_atomic_write (v, size); -WARN_ON_ONCE (IS_ENABLED (CONFIG_DEBUG_ATOMIC ) && ((unsigned long )v & (size -1 ))); +instrument_atomic_check_alignment (v, size); }/**
@@ -98,7 +109,7 @@ static __always_inline void instrument_atomic_read_write(const volatile void *v, {kasan_check_write (v, size);kcsan_check_atomic_read_write (v, size); -WARN_ON_ONCE (IS_ENABLED (CONFIG_DEBUG_ATOMIC ) && ((unsigned long )v & (size -1 ))); +instrument_atomic_check_alignment (v, size); }/**
lib/Kconfig.debug +8 -0
@@ -1366,6 +1366,14 @@ config DEBUG_ATOMIC This option has potentially significant overhead. +config DEBUG_ATOMIC_LARGEST_ALIGN + bool "Check alignment only up to __aligned_largest" + depends on DEBUG_ATOMIC + help + If you say Y here then the check for natural alignment of + atomic accesses will be constrained to the compiler's largest + alignment for scalar types. + menu "Lock Debugging (spinlocks, mutexes, etc...)" config LOCK_DEBUGGING_SUPPORT
Signature · 1 line
2.49.1
Andrew Morton
maintainerQuoted 5 lines · On Tue, 16 Dec 2025 17:31:05 +1100 Finn Thain <[email protected]> wrote:
This series adds the
__alignedattribute toatomic_tandatomic64_tdefinitions ininclude/linuxandinclude/asm-generic(respectively) to get natural alignment of both types on csky, m68k, microblaze, nios2, openrisc and sh.
Quoted 7 lines
This series also adds
Kconfigoptions to enable a new run-time warning to help reveal misaligned atomic accesses on platforms which don't trap that.The performance impact is expected to vary across platforms and workloads. The measurements I made on m68k show that some workloads run faster and others slower.
Looks nice, thanks.
I don't know which tree this is aimed at. I grabbed a copy for mm.git's mm-nonmm-unstable tree, can drop it again if this pops up in linux-next via another route.