Linux EXT4 FS development
 help / color / mirror / Atom feed
* [PATCH v3 0/8] Convert barrier pairs to acquire/release for better performance
@ 2026-09-02  7:47 Jinjie Ruan
  2026-09-02  7:47 ` [PATCH v3 1/8] user_namespace: Use acquire/release for nr_extents synchronization Jinjie Ruan
                   ` (7 more replies)
  0 siblings, 8 replies; 18+ messages in thread
From: Jinjie Ruan @ 2026-09-02  7:47 UTC (permalink / raw)
  To: bcrl, viro, brauner, jack, tytso, adilger.kernel, libaokun,
	ojaswin, ritesh.list, yi.zhang, sforshee, akpm, pmladek, rostedt,
	andriy.shevchenko, linux, senozhatsky, kees, tglx, linux-fsdevel,
	linux-aio, linux-kernel, linux-ext4
  Cc: ruanjinjie

Hi,

This series converts some existing smp_wmb()/smp_rmb() barrier pairs to
smp_store_release()/smp_load_acquire() across various subsystems.

Background
==========

Many architectures support load acquire and store release instructions
which can replace explicit memory barriers and save cycles. As noted
in the ARM architecture reference [1]:

  "Weaker ordering requirements that are imposed by Load-Acquire and
   Store-Release instructions allow for micro-architectural
   optimizations, which could reduce some of the performance impacts
   that are otherwise imposed by an explicit memory barrier.

   If the ordering requirement is satisfied using either a Load-Acquire
   or Store-Release, then it would be preferable to use these
   instructions instead of a DMB."

On arm64, a typical seqcount [2] read loop requires 13 cycles with DMB
barriers. Replacing the read barrier with smp_load_acquire() reduces
this to 8 cycles on an Ampere Altra.

We also observed significant barrier overhead while profiling Unxibench
syscall test on arm64: a single getuid() call is ~8ns slower than on
a comparable x86 system, with the dominant cost in map_id_up()'s smp_rmb(),
which is a DMB ISHLD on arm64. Converting it to smp_load_acquire() allows
the use of LDAR, eliminating the measurable overhead.

This motivated a broader search for existing barrier pairs that can
be converted to the lighter acquire/release semantics.

Changes
=======

Each patch in this series targets a specific barrier pair where the
publish/subscribe pattern is already present:

- Writers populate data, then publish a flag/count/pointer via
  smp_store_release()

- Readers load the flag/count/pointer via smp_load_acquire(), then
  consume the data

This preserves the existing memory ordering guarantees while allowing
architectures with native acquire/release instructions (e.g. arm64's
STLR/LDAR) to avoid the cost of full one-way barriers (DMB ISHST/ISHLD).
On architectures without native support, the generated code is
generally no worse than the explicit barrier pair.

The conversions are mechanical and no functional change is intended.

Testing (Kunpeng HIP09 arm64 server)
====================================

1. UNIXBENCH syscall
	Baseline: 715.27
	Patched:  718.83
	Improvement: +0.50%

2. fs/aio (fio + null_blk, 4 jobs):
	Baseline: 1441k IOPS, 86.46us
	Patched:  1452k IOPS, 85.80us
	Improvement: ~0.8%

Both improvements are consistent across runs and align with the
expected savings from replacing DMB with LDAR/STLR on arm64.

[1]: https://support.arm.com/documentation/102336/0100/Load-Acquire-and-Store-Release-instructions
[2]: https://github.com/torvalds/linux/commit/d0dd066a0fa26d55c19ace9e89dedd9504c5bcba

Changes in v3:
- Add Reviewed-by.
- Split out network patch set as Kuniyuki suggested.
- Link to v2: https://lore.kernel.org/all/20260901024234.135119-1-ruanjinjie@huawei.com/

Changes in v2:
- Fix pre-existing issue for ext4 and 8021q [3].
- Fix missing copy_mnt_idmap() udapte [3].
- Drop nacked isotp patch.
- Add test data.
- Add Reviewed-by and update fs patch as Jan suggested.

[3]: https://sashiko.dev/#/patchset/20260825095422.3166067-1-ruanjinjie%40huawei.com

Jinjie Ruan (8):
  user_namespace: Use acquire/release for nr_extents synchronization
  lib/vsprintf: Use acquire/release for ptr_key publication
  fs: aio: Use acquire/release for ring->tail publication
  fs: Use acquire/release for fdtable resize synchronization
  pidfs: Use test_bit_acquire() for attr flag tests
  super: Use acquire for SB_BORN check in super_cache_count()
  ext4: Fix out-of-bounds read in ext4_get_group_info()
  ext4: Convert group-count barrier protocol to acquire/release

 fs/aio.c                | 10 ++++------
 fs/ext4/balloc.c        |  2 +-
 fs/ext4/ext4.h          | 10 +++-------
 fs/ext4/mballoc.c       |  6 ++----
 fs/ext4/resize.c        | 19 +++++++++++--------
 fs/file.c               | 10 ++++------
 fs/mnt_idmapping.c      |  5 ++---
 fs/pidfs.c              |  6 ++----
 fs/super.c              |  6 ++----
 kernel/user_namespace.c | 24 +++++++++++++-----------
 lib/vsprintf.c          | 11 ++++-------
 11 files changed, 48 insertions(+), 61 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 1/8] user_namespace: Use acquire/release for nr_extents synchronization
  2026-09-02  7:47 [PATCH v3 0/8] Convert barrier pairs to acquire/release for better performance Jinjie Ruan
@ 2026-09-02  7:47 ` Jinjie Ruan
  2026-09-02  7:53   ` sashiko-bot
  2026-09-02 10:09   ` Bradley Morgan
  2026-09-02  7:47 ` [PATCH v3 2/8] lib/vsprintf: Use acquire/release for ptr_key publication Jinjie Ruan
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 18+ messages in thread
From: Jinjie Ruan @ 2026-09-02  7:47 UTC (permalink / raw)
  To: bcrl, viro, brauner, jack, tytso, adilger.kernel, libaokun,
	ojaswin, ritesh.list, yi.zhang, sforshee, akpm, pmladek, rostedt,
	andriy.shevchenko, linux, senozhatsky, kees, tglx, linux-fsdevel,
	linux-aio, linux-kernel, linux-ext4
  Cc: ruanjinjie

Replace smp_wmb()/smp_rmb() with smp_store_release()/smp_load_acquire()
when publishing and consuming `nr_extents`. This expresses the
publish/subscribe pattern more clearly and allows architectures with
native acquire/release instructions (e.g. arm64's STLR/LDAR) to avoid
the cost of full one-way barriers (DMB ISHST/ISHLD).

No functional change intended.

Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Seth Forshee <sforshee@kernel.org>
Cc: Kees Cook <kees@kernel.org>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Assisted-by: DeepSeek:DeepSeek-V3
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
v2:
- Add missing load replace in copy_mnt_idmap()
---
 fs/mnt_idmapping.c      |  5 ++---
 kernel/user_namespace.c | 24 +++++++++++++-----------
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/fs/mnt_idmapping.c b/fs/mnt_idmapping.c
index cb61fbdb52e9..612b266ab3da 100644
--- a/fs/mnt_idmapping.c
+++ b/fs/mnt_idmapping.c
@@ -219,10 +219,9 @@ EXPORT_SYMBOL_GPL(vfsgid_in_group_p);
 static int copy_mnt_idmap(struct uid_gid_map *map_from,
 			  struct uid_gid_map *map_to)
 {
+	/* Pairs with smp_store_release() in map_write(). */
+	u32 nr_extents = smp_load_acquire(&map_from->nr_extents);
 	struct uid_gid_extent *forward, *reverse;
-	u32 nr_extents = READ_ONCE(map_from->nr_extents);
-	/* Pairs with smp_wmb() when writing the idmapping. */
-	smp_rmb();
 
 	/*
 	 * Don't blindly copy @map_to into @map_from if nr_extents is
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 0bed462e9b2a..576b667a8813 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -317,9 +317,9 @@ map_id_range_down_base(unsigned extents, struct uid_gid_map *map, u32 id, u32 co
 
 static u32 map_id_range_down(struct uid_gid_map *map, u32 id, u32 count)
 {
+	/* Pairs with smp_store_release() in map_write(). */
+	unsigned int extents = smp_load_acquire(&map->nr_extents);
 	struct uid_gid_extent *extent;
-	unsigned extents = map->nr_extents;
-	smp_rmb();
 
 	if (extents <= UID_GID_MAP_MAX_BASE_EXTENTS)
 		extent = map_id_range_down_base(extents, map, id, count);
@@ -383,9 +383,9 @@ map_id_range_up_max(unsigned extents, struct uid_gid_map *map, u32 id, u32 count
 
 u32 map_id_range_up(struct uid_gid_map *map, u32 id, u32 count)
 {
+	/* Pairs with smp_store_release() in map_write(). */
+	unsigned int extents = smp_load_acquire(&map->nr_extents);
 	struct uid_gid_extent *extent;
-	unsigned extents = map->nr_extents;
-	smp_rmb();
 
 	if (extents <= UID_GID_MAP_MAX_BASE_EXTENTS)
 		extent = map_id_range_up_base(extents, map, id, count);
@@ -676,9 +676,9 @@ static int projid_m_show(struct seq_file *seq, void *v)
 static void *m_start(struct seq_file *seq, loff_t *ppos,
 		     struct uid_gid_map *map)
 {
+	/* Pairs with smp_store_release() in map_write(). */
+	unsigned int extents = smp_load_acquire(&map->nr_extents);
 	loff_t pos = *ppos;
-	unsigned extents = map->nr_extents;
-	smp_rmb();
 
 	if (pos >= extents)
 		return NULL;
@@ -967,9 +967,11 @@ static ssize_t map_write(struct file *file, const char __user *buf,
 	 * desired behavior is to see the values of the extents that
 	 * were written before the count of the extents.
 	 *
-	 * To achieve this smp_wmb() is used on guarantee the write
-	 * order and smp_rmb() is guaranteed that we don't have crazy
-	 * architectures returning stale data.
+	 * The nr_extents field is the publish point for the extent
+	 * data.  Writers use smp_store_release() to ensure all extent
+	 * data is visible before nr_extents is updated.  Readers use
+	 * smp_load_acquire() to ensure they see a consistent view of
+	 * the extent data when reading nr_extents.
 	 */
 	mutex_lock(&userns_state_mutex);
 
@@ -1098,8 +1100,8 @@ static ssize_t map_write(struct file *file, const char __user *buf,
 		map->forward = new_map.forward;
 		map->reverse = new_map.reverse;
 	}
-	smp_wmb();
-	map->nr_extents = new_map.nr_extents;
+	/* Pairs with smp_load_acquire() in map_id_range_{up,down}() and m_start(). */
+	smp_store_release(&map->nr_extents, new_map.nr_extents);
 
 	*ppos = count;
 	ret = count;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 2/8] lib/vsprintf: Use acquire/release for ptr_key publication
  2026-09-02  7:47 [PATCH v3 0/8] Convert barrier pairs to acquire/release for better performance Jinjie Ruan
  2026-09-02  7:47 ` [PATCH v3 1/8] user_namespace: Use acquire/release for nr_extents synchronization Jinjie Ruan
@ 2026-09-02  7:47 ` Jinjie Ruan
  2026-09-02  7:52   ` sashiko-bot
  2026-09-02  7:48 ` [PATCH v3 3/8] fs: aio: Use acquire/release for ring->tail publication Jinjie Ruan
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Jinjie Ruan @ 2026-09-02  7:47 UTC (permalink / raw)
  To: bcrl, viro, brauner, jack, tytso, adilger.kernel, libaokun,
	ojaswin, ritesh.list, yi.zhang, sforshee, akpm, pmladek, rostedt,
	andriy.shevchenko, linux, senozhatsky, kees, tglx, linux-fsdevel,
	linux-aio, linux-kernel, linux-ext4
  Cc: ruanjinjie

Replace the smp_wmb() + WRITE_ONCE() and READ_ONCE() + smp_rmb() barrier
pair with smp_store_release()/smp_load_acquire() on filled_random_ptr_key.

This expresses the publish/subscribe pattern more clearly and allows
architectures with native acquire/release instructions (e.g. arm64's
STLR/LDAR) to avoid the cost of full one-way barriers (DMB ISHST/ISHLD).

No functional change intended.

Cc: Petr Mladek <pmladek@suse.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Assisted-by: DeepSeek:DeepSeek-V3
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
 lib/vsprintf.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 1d95ab9314bf..90d0a724eadd 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -762,9 +762,8 @@ static int fill_ptr_key(struct notifier_block *nb, unsigned long action, void *d
 {
 	get_random_bytes(&ptr_key, sizeof(ptr_key));
 
-	/* Pairs with smp_rmb() before reading ptr_key. */
-	smp_wmb();
-	WRITE_ONCE(filled_random_ptr_key, true);
+	/* Pairs with smp_load_acquire() before reading ptr_key. */
+	smp_store_release(&filled_random_ptr_key, true);
 	return NOTIFY_DONE;
 }
 
@@ -781,12 +780,10 @@ static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
 {
 	unsigned long hashval;
 
-	if (!READ_ONCE(filled_random_ptr_key))
+	/* Pairs with smp_store_release() after writing ptr_key. */
+	if (!smp_load_acquire(&filled_random_ptr_key))
 		return -EBUSY;
 
-	/* Pairs with smp_wmb() after writing ptr_key. */
-	smp_rmb();
-
 #ifdef CONFIG_64BIT
 	hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key);
 	/*
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 3/8] fs: aio: Use acquire/release for ring->tail publication
  2026-09-02  7:47 [PATCH v3 0/8] Convert barrier pairs to acquire/release for better performance Jinjie Ruan
  2026-09-02  7:47 ` [PATCH v3 1/8] user_namespace: Use acquire/release for nr_extents synchronization Jinjie Ruan
  2026-09-02  7:47 ` [PATCH v3 2/8] lib/vsprintf: Use acquire/release for ptr_key publication Jinjie Ruan
@ 2026-09-02  7:48 ` Jinjie Ruan
  2026-09-02  7:57   ` sashiko-bot
  2026-09-02  7:48 ` [PATCH v3 4/8] fs: Use acquire/release for fdtable resize synchronization Jinjie Ruan
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Jinjie Ruan @ 2026-09-02  7:48 UTC (permalink / raw)
  To: bcrl, viro, brauner, jack, tytso, adilger.kernel, libaokun,
	ojaswin, ritesh.list, yi.zhang, sforshee, akpm, pmladek, rostedt,
	andriy.shevchenko, linux, senozhatsky, kees, tglx, linux-fsdevel,
	linux-aio, linux-kernel, linux-ext4
  Cc: ruanjinjie

Replace the smp_wmb() + WRITE_ONCE(ring->tail) and READ_ONCE(ring->tail)
+ smp_rmb() barrier pair with smp_store_release()/smp_load_acquire()
on `ring->tail`.

This expresses the publish/subscribe pattern more clearly and allows
architectures with native acquire/release instructions (e.g. arm64's
STLR/LDAR) to avoid the cost of full one-way barriers (DMB ISHST/ISHLD).

The release ensures event data written before updating ring->tail is
visible to readers that observe the new tail value via acquire, which
is exactly the ordering the barrier pair provided.

No functional change intended.

Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Benjamin LaHaise <bcrl@kvack.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Assisted-by: DeepSeek:DeepSeek-V3
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
 fs/aio.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/aio.c b/fs/aio.c
index d78acc69f487..a0279e059e97 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1206,13 +1206,12 @@ static void aio_complete(struct aio_kiocb *iocb)
 	/* after flagging the request as done, we
 	 * must never even look at it again
 	 */
-	smp_wmb();	/* make event visible before updating tail */
-
 	ctx->tail = tail;
 
 	ring = folio_address(ctx->ring_folios[0]);
 	head = ring->head;
-	ring->tail = tail;
+	/* Make event visible before updating tail */
+	smp_store_release(&ring->tail, tail);
 	flush_dcache_folio(ctx->ring_folios[0]);
 
 	ctx->completed_events++;
@@ -1288,13 +1287,12 @@ static long aio_read_events_ring(struct kioctx *ctx,
 	/* Access to ->ring_folios here is protected by ctx->ring_lock. */
 	ring = folio_address(ctx->ring_folios[0]);
 	head = ring->head;
-	tail = ring->tail;
-
 	/*
 	 * Ensure that once we've read the current tail pointer, that
 	 * we also see the events that were stored up to the tail.
+	 * Pairs with smp_store_release() in aio_complete().
 	 */
-	smp_rmb();
+	tail = smp_load_acquire(&ring->tail);
 
 	pr_debug("h%u t%u m%u\n", head, tail, ctx->nr_events);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 4/8] fs: Use acquire/release for fdtable resize synchronization
  2026-09-02  7:47 [PATCH v3 0/8] Convert barrier pairs to acquire/release for better performance Jinjie Ruan
                   ` (2 preceding siblings ...)
  2026-09-02  7:48 ` [PATCH v3 3/8] fs: aio: Use acquire/release for ring->tail publication Jinjie Ruan
@ 2026-09-02  7:48 ` Jinjie Ruan
  2026-09-02  7:53   ` sashiko-bot
  2026-09-02  7:48 ` [PATCH v3 5/8] pidfs: Use test_bit_acquire() for attr flag tests Jinjie Ruan
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Jinjie Ruan @ 2026-09-02  7:48 UTC (permalink / raw)
  To: bcrl, viro, brauner, jack, tytso, adilger.kernel, libaokun,
	ojaswin, ritesh.list, yi.zhang, sforshee, akpm, pmladek, rostedt,
	andriy.shevchenko, linux, senozhatsky, kees, tglx, linux-fsdevel,
	linux-aio, linux-kernel, linux-ext4
  Cc: ruanjinjie

Replace the smp_wmb()/smp_rmb() barrier pair with
smp_store_release()/smp_load_acquire() on `files->resize_in_progress`.
The flag is the publish point for fdtable expansion: writers clear it
via release after rcu_assign_pointer(), readers check it via acquire
before rcu_dereference_sched(). Observing it clear guarantees the new
fdt pointer is visible.

This expresses the pattern more clearly and allows cheaper one-way
barriers on weakly-ordered architectures (e.g. arm64 STLR/LDAR vs
DMB ISHST/ISHLD).

Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Reviewed-by: Jan Kara <jack@suse.cz>
Assisted-by: DeepSeek:DeepSeek-V3
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
 fs/file.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index 628ca07dc4b1..86c035d459f2 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -273,8 +273,6 @@ static int expand_fdtable(struct files_struct *files, unsigned int nr)
 	rcu_assign_pointer(files->fdt, new_fdt);
 	if (cur_fdt != &files->fdtab)
 		call_rcu(&cur_fdt->rcu, free_fdtable_rcu);
-	/* coupled with smp_rmb() in fd_install() */
-	smp_wmb();
 	return 0;
 }
 
@@ -313,7 +311,8 @@ static int expand_files(struct files_struct *files, unsigned int nr)
 	/* All good, so we try */
 	files->resize_in_progress = true;
 	error = expand_fdtable(files, nr);
-	files->resize_in_progress = false;
+	/* coupled with smp_load_acquire() in fd_install() */
+	smp_store_release(&files->resize_in_progress, false);
 
 	wake_up_all(&files->resize_wait);
 	return error;
@@ -685,13 +684,12 @@ void fd_install(unsigned int fd, struct file *file)
 		return;
 
 	rcu_read_lock_sched();
-	if (unlikely(files->resize_in_progress)) {
+	/* coupled with smp_store_release() in expand_files() */
+	if (unlikely(smp_load_acquire(&files->resize_in_progress))) {
 		rcu_read_unlock_sched();
 		fd_install_slowpath(fd, file);
 		return;
 	}
-	/* coupled with smp_wmb() in expand_fdtable() */
-	smp_rmb();
 	fdt = rcu_dereference_sched(files->fdt);
 	VFS_BUG_ON(rcu_access_pointer(fdt->fd[fd]) != NULL);
 	rcu_assign_pointer(fdt->fd[fd], file);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 5/8] pidfs: Use test_bit_acquire() for attr flag tests
  2026-09-02  7:47 [PATCH v3 0/8] Convert barrier pairs to acquire/release for better performance Jinjie Ruan
                   ` (3 preceding siblings ...)
  2026-09-02  7:48 ` [PATCH v3 4/8] fs: Use acquire/release for fdtable resize synchronization Jinjie Ruan
@ 2026-09-02  7:48 ` Jinjie Ruan
  2026-09-02  7:55   ` sashiko-bot
  2026-09-02  7:48 ` [PATCH v3 6/8] super: Use acquire for SB_BORN check in super_cache_count() Jinjie Ruan
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Jinjie Ruan @ 2026-09-02  7:48 UTC (permalink / raw)
  To: bcrl, viro, brauner, jack, tytso, adilger.kernel, libaokun,
	ojaswin, ritesh.list, yi.zhang, sforshee, akpm, pmladek, rostedt,
	andriy.shevchenko, linux, senozhatsky, kees, tglx, linux-fsdevel,
	linux-aio, linux-kernel, linux-ext4
  Cc: ruanjinjie

Replace test_bit() + smp_rmb() with test_bit_acquire() for
PIDFS_ATTR_BIT_EXIT and PIDFS_ATTR_BIT_COREDUMP tests in pidfd_info().

The acquire semantics ensure that if the flag is observed set, the
associated attr fields written before smp_wmb() + set_bit() are
also visible.

Writers keep smp_wmb() + set_bit() since no release bitop exists.

Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Assisted-by: DeepSeek:DeepSeek-V3
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
 fs/pidfs.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/pidfs.c b/fs/pidfs.c
index a6a643f15d08..2cd0fab73180 100644
--- a/fs/pidfs.c
+++ b/fs/pidfs.c
@@ -393,8 +393,7 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
 
 	attr = READ_ONCE(pid->attr);
 	if (mask & PIDFD_INFO_EXIT) {
-		if (test_bit(PIDFS_ATTR_BIT_EXIT, &attr->attr_mask)) {
-			smp_rmb();
+		if (test_bit_acquire(PIDFS_ATTR_BIT_EXIT, &attr->attr_mask)) {
 			kinfo.mask |= PIDFD_INFO_EXIT;
 #ifdef CONFIG_CGROUPS
 			kinfo.cgroupid = attr->cgroupid;
@@ -405,8 +404,7 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
 	}
 
 	if (mask & PIDFD_INFO_COREDUMP) {
-		if (test_bit(PIDFS_ATTR_BIT_COREDUMP, &attr->attr_mask)) {
-			smp_rmb();
+		if (test_bit_acquire(PIDFS_ATTR_BIT_COREDUMP, &attr->attr_mask)) {
 			kinfo.mask |= PIDFD_INFO_COREDUMP | PIDFD_INFO_COREDUMP_SIGNAL | PIDFD_INFO_COREDUMP_CODE;
 			kinfo.coredump_mask = attr->coredump_mask;
 			kinfo.coredump_signal = attr->coredump_signal;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 6/8] super: Use acquire for SB_BORN check in super_cache_count()
  2026-09-02  7:47 [PATCH v3 0/8] Convert barrier pairs to acquire/release for better performance Jinjie Ruan
                   ` (4 preceding siblings ...)
  2026-09-02  7:48 ` [PATCH v3 5/8] pidfs: Use test_bit_acquire() for attr flag tests Jinjie Ruan
@ 2026-09-02  7:48 ` Jinjie Ruan
  2026-09-02  7:58   ` sashiko-bot
  2026-09-02  7:48 ` [PATCH v3 7/8] ext4: Fix out-of-bounds read in ext4_get_group_info() Jinjie Ruan
  2026-09-02  7:48 ` [PATCH v3 8/8] ext4: Convert group-count barrier protocol to acquire/release Jinjie Ruan
  7 siblings, 1 reply; 18+ messages in thread
From: Jinjie Ruan @ 2026-09-02  7:48 UTC (permalink / raw)
  To: bcrl, viro, brauner, jack, tytso, adilger.kernel, libaokun,
	ojaswin, ritesh.list, yi.zhang, sforshee, akpm, pmladek, rostedt,
	andriy.shevchenko, linux, senozhatsky, kees, tglx, linux-fsdevel,
	linux-aio, linux-kernel, linux-ext4
  Cc: ruanjinjie

The active SB_BORN check in super_cache_count() pairs with the
smp_store_release() in super_wake() when publishing a newly initialized
superblock.

Replace the historical independent smp_rmb() barrier with an acquire load
on sb->s_flags via super_flags(). This expresses the publish-subscribe
pattern more clearly and allows weakly-ordered architectures like arm64
to utilize efficient native instructions (e.g., LDAR) instead of a full
one-way barrier.

Also remove the outdated memory barrier comment in super_cache_count(),
as the underlying super_flags() implementation already self-documents
the matched smp_store_release() in super_wake().

Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Assisted-by: Gemini:Gemini-3.1
Assisted-by: DeepSeek:DeepSeek-V3
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
 fs/super.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index 05e443173038..caa6189e4057 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -267,12 +267,10 @@ static unsigned long super_cache_count(struct shrinker *shrink,
 	 * However, if we are currently mounting the superblock, the underlying
 	 * filesystem might be in a state of partial construction and hence it
 	 * is dangerous to access it.  super_trylock_shared() uses a SB_BORN check
-	 * to avoid this situation, so do the same here. The memory barrier is
-	 * matched with the one in mount_fs() as we don't hold locks here.
+	 * to avoid this situation, so do the same here.
 	 */
-	if (!(sb->s_flags & SB_BORN))
+	if (!super_flags(sb, SB_BORN))
 		return 0;
-	smp_rmb();
 
 	if (sb->s_op && sb->s_op->nr_cached_objects &&
 	    super_fs_objects_eligible(sc))
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 7/8] ext4: Fix out-of-bounds read in ext4_get_group_info()
  2026-09-02  7:47 [PATCH v3 0/8] Convert barrier pairs to acquire/release for better performance Jinjie Ruan
                   ` (5 preceding siblings ...)
  2026-09-02  7:48 ` [PATCH v3 6/8] super: Use acquire for SB_BORN check in super_cache_count() Jinjie Ruan
@ 2026-09-02  7:48 ` Jinjie Ruan
  2026-09-02  8:01   ` sashiko-bot
  2026-09-02  7:48 ` [PATCH v3 8/8] ext4: Convert group-count barrier protocol to acquire/release Jinjie Ruan
  7 siblings, 1 reply; 18+ messages in thread
From: Jinjie Ruan @ 2026-09-02  7:48 UTC (permalink / raw)
  To: bcrl, viro, brauner, jack, tytso, adilger.kernel, libaokun,
	ojaswin, ritesh.list, yi.zhang, sforshee, akpm, pmladek, rostedt,
	andriy.shevchenko, linux, senozhatsky, kees, tglx, linux-fsdevel,
	linux-aio, linux-kernel, linux-ext4
  Cc: ruanjinjie

A plain read of s_groups_count in ext4_get_group_info() allows CPU
load-load reordering. On weak memory models, speculative prefetch of
s_group_info prior to the boundary check could lead to an out-of-bounds
read if a concurrent online resize expands the array and increments
s_groups_count.

The data race occurs between the ioctl configuration path (holding the
resize lock via ext4_resize_begin) and the lockless metadata lookup path:

   CPU 0 (Writer, Resize Lock)                CPU 1 (Reader, Lockless)
   ---------------------------                ------------------------
   ext4_ioctl()
     [EXT4_IOC_GROUP_ADD]
     ext4_ioctl_group_add()
       ext4_resize_begin() // Takes lock
       ext4_group_add()
         ext4_mb_alloc_groupinfo()
           // Publishes expanded array via RCU
           rcu_assign_pointer(s_group_info, ...)

         ext4_flex_group_add()
           ext4_update_super()
                                              ext4_get_group_info()
                                                // Speculative / out-of-order read
                                                [Loads old/smaller s_group_info pointer]
             [Plain C store / smp_wmb()]
             sbi->s_groups_count += ...;
                                                // Reads new s_groups_count,
                                                // boundary check passes
                                                if (group >= s_groups_count)

                                                // Out-of-bounds array access!
                                                sbi_array_rcu_deref(..., s_group_info)

Fix this by using ext4_get_groups_count() to enforce acquire semantics.

Cc: stable@vger.kernel.org
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: Baokun Li <libaokun@linux.alibaba.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
Cc: Zhang Yi <yi.zhang@huawei.com>
Fixes: 5354b2af3406 ("ext4: allow ext4_get_group_info() to fail")
Link: https://sashiko.dev/#/patchset/20260825095422.3166067-1-ruanjinjie%40huawei.com
Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
 fs/ext4/balloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 52f4c5169f91..778fe8788f06 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -329,7 +329,7 @@ struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
 	struct ext4_group_info **grp_info;
 	long indexv, indexh;
 
-	if (unlikely(group >= EXT4_SB(sb)->s_groups_count))
+	if (unlikely(group >= ext4_get_groups_count(sb)))
 		return NULL;
 	if (unlikely(!EXT4_SB(sb)->s_group_info))
 		return NULL;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 8/8] ext4: Convert group-count barrier protocol to acquire/release
  2026-09-02  7:47 [PATCH v3 0/8] Convert barrier pairs to acquire/release for better performance Jinjie Ruan
                   ` (6 preceding siblings ...)
  2026-09-02  7:48 ` [PATCH v3 7/8] ext4: Fix out-of-bounds read in ext4_get_group_info() Jinjie Ruan
@ 2026-09-02  7:48 ` Jinjie Ruan
  2026-09-02  7:58   ` sashiko-bot
  7 siblings, 1 reply; 18+ messages in thread
From: Jinjie Ruan @ 2026-09-02  7:48 UTC (permalink / raw)
  To: bcrl, viro, brauner, jack, tytso, adilger.kernel, libaokun,
	ojaswin, ritesh.list, yi.zhang, sforshee, akpm, pmladek, rostedt,
	andriy.shevchenko, linux, senozhatsky, kees, tglx, linux-fsdevel,
	linux-aio, linux-kernel, linux-ext4
  Cc: ruanjinjie

During an online resize, reading s_groups_count and s_blockfile_groups
requires strict ordering against subsequent initialized block group
metadata.

Replace the historical smp_wmb()/smp_rmb() pairs with smp_store_release()
and smp_load_acquire(). This formalizes the publish-subscribe pattern
and allows weakly-ordered architectures (e.g., arm64) to utilize native
STLR/LDAR instructions instead of full DMB fences.

Update the documentation in resize.c and ext4.h accordingly.

Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: Baokun Li <libaokun@linux.alibaba.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
Cc: Zhang Yi <yi.zhang@huawei.com>
Assisted-by: Gemini:Gemini-3.1
Assisted-by: DeepSeek:DeepSeek-V3
Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
 fs/ext4/ext4.h    | 10 +++-------
 fs/ext4/mballoc.c |  6 ++----
 fs/ext4/resize.c  | 19 +++++++++++--------
 3 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 724a27e8be61..d70b9cb09155 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -3542,16 +3542,12 @@ static inline void ext4_isize_set(struct ext4_inode *raw_inode, loff_t i_size)
 }
 
 /*
- * Reading s_groups_count requires using smp_rmb() afterwards.  See
- * the locking protocol documented in the comments of ext4_group_add()
- * in resize.c
+ * Reading s_groups_count uses acquire semantics.
  */
 static inline ext4_group_t ext4_get_groups_count(struct super_block *sb)
 {
-	ext4_group_t	ngroups = EXT4_SB(sb)->s_groups_count;
-
-	smp_rmb();
-	return ngroups;
+	/* Pairs with smp_store_release() in ext4_update_super() */
+	return smp_load_acquire(&EXT4_SB(sb)->s_groups_count);
 }
 
 static inline ext4_group_t ext4_flex_group(struct ext4_sb_info *sbi,
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 06171a11db12..a15285224cdf 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -899,10 +899,8 @@ static ext4_group_t ext4_get_allocation_groups_count(
 
 	/* non-extent files are limited to low blocks/groups */
 	if (!(ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS)))
-		ngroups = EXT4_SB(ac->ac_sb)->s_blockfile_groups;
-
-	/* Pairs with smp_wmb() in ext4_update_super() */
-	smp_rmb();
+		/* Pairs with smp_store_release() in ext4_update_super() */
+		ngroups = smp_load_acquire(&EXT4_SB(ac->ac_sb)->s_blockfile_groups);
 
 	return ngroups;
 }
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 2c5b851c552a..5e3ad8393cf8 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1462,11 +1462,11 @@ static void ext4_update_super(struct super_block *sb,
 	 *
 	 * The precise rules we use are:
 	 *
-	 * * Writers must perform a smp_wmb() after updating all
-	 *   dependent data and before modifying the groups count
+	 * * Writers must use a release store when updating the groups count
+	 *   after all dependent data has been updated
 	 *
-	 * * Readers must perform an smp_rmb() after reading the groups
-	 *   count and before reading any dependent data.
+	 * * Readers must use an acquire load when reading the groups
+	 *   count before reading any dependent data.
 	 *
 	 * NB. These rules can be relaxed when checking the group count
 	 * while freeing data, as we can only allocate from a block
@@ -1474,12 +1474,15 @@ static void ext4_update_super(struct super_block *sb,
 	 * only then free after serialising in turn against that
 	 * allocation.
 	 */
-	smp_wmb();
 
 	/* Update the global fs size fields */
-	sbi->s_groups_count += flex_gd->count;
-	sbi->s_blockfile_groups = min(sbi->s_groups_count,
-			(EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb)));
+	/* Pairs with smp_load_acquire() in ext4_get_groups_count() */
+	smp_store_release(&sbi->s_groups_count,
+			  sbi->s_groups_count + flex_gd->count);
+	/* Pairs with smp_load_acquire() in ext4_get_allocation_groups_count() */
+	smp_store_release(&sbi->s_blockfile_groups,
+			  min(sbi->s_groups_count,
+			      (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))));
 
 	/* Update the reserved block counts only once the new group is
 	 * active. */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 2/8] lib/vsprintf: Use acquire/release for ptr_key publication
  2026-09-02  7:47 ` [PATCH v3 2/8] lib/vsprintf: Use acquire/release for ptr_key publication Jinjie Ruan
@ 2026-09-02  7:52   ` sashiko-bot
  0 siblings, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-09-02  7:52 UTC (permalink / raw)
  To: Jinjie Ruan; +Cc: tytso, linux-ext4

> Replace the smp_wmb() + WRITE_ONCE() and READ_ONCE() + smp_rmb() barrier
> pair with smp_store_release()/smp_load_acquire() on filled_random_ptr_key.
> 
> This expresses the publish/subscribe pattern more clearly and allows
> architectures with native acquire/release instructions (e.g. arm64's
> STLR/LDAR) to avoid the cost of full one-way barriers (DMB ISHST/ISHLD).
> 
> No functional change intended.
> 
> Cc: Petr Mladek <pmladek@suse.com>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Assisted-by: DeepSeek:DeepSeek-V3
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902074805.398540-1-ruanjinjie@huawei.com?part=2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 1/8] user_namespace: Use acquire/release for nr_extents synchronization
  2026-09-02  7:47 ` [PATCH v3 1/8] user_namespace: Use acquire/release for nr_extents synchronization Jinjie Ruan
@ 2026-09-02  7:53   ` sashiko-bot
  2026-09-02 10:09   ` Bradley Morgan
  1 sibling, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-09-02  7:53 UTC (permalink / raw)
  To: Jinjie Ruan; +Cc: tytso, linux-ext4

> Replace smp_wmb()/smp_rmb() with smp_store_release()/smp_load_acquire()
> when publishing and consuming `nr_extents`. This expresses the
> publish/subscribe pattern more clearly and allows architectures with
> native acquire/release instructions (e.g. arm64's STLR/LDAR) to avoid
> the cost of full one-way barriers (DMB ISHST/ISHLD).
> 
> No functional change intended.
> 
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Seth Forshee <sforshee@kernel.org>
> Cc: Kees Cook <kees@kernel.org>
> Cc: Aleksa Sarai <cyphar@cyphar.com>
> Assisted-by: DeepSeek:DeepSeek-V3
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902074805.398540-1-ruanjinjie@huawei.com?part=1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 4/8] fs: Use acquire/release for fdtable resize synchronization
  2026-09-02  7:48 ` [PATCH v3 4/8] fs: Use acquire/release for fdtable resize synchronization Jinjie Ruan
@ 2026-09-02  7:53   ` sashiko-bot
  0 siblings, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-09-02  7:53 UTC (permalink / raw)
  To: Jinjie Ruan; +Cc: tytso, linux-ext4

> Replace the smp_wmb()/smp_rmb() barrier pair with
> smp_store_release()/smp_load_acquire() on `files->resize_in_progress`.
> The flag is the publish point for fdtable expansion: writers clear it
> via release after rcu_assign_pointer(), readers check it via acquire
> before rcu_dereference_sched(). Observing it clear guarantees the new
> fdt pointer is visible.
> 
> This expresses the pattern more clearly and allows cheaper one-way
> barriers on weakly-ordered architectures (e.g. arm64 STLR/LDAR vs
> DMB ISHST/ISHLD).
> 
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Reviewed-by: Jan Kara <jack@suse.cz>
> Assisted-by: DeepSeek:DeepSeek-V3
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902074805.398540-1-ruanjinjie@huawei.com?part=4


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 5/8] pidfs: Use test_bit_acquire() for attr flag tests
  2026-09-02  7:48 ` [PATCH v3 5/8] pidfs: Use test_bit_acquire() for attr flag tests Jinjie Ruan
@ 2026-09-02  7:55   ` sashiko-bot
  0 siblings, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-09-02  7:55 UTC (permalink / raw)
  To: Jinjie Ruan; +Cc: linux-ext4, tytso

> Replace test_bit() + smp_rmb() with test_bit_acquire() for
> PIDFS_ATTR_BIT_EXIT and PIDFS_ATTR_BIT_COREDUMP tests in pidfd_info().
> 
> The acquire semantics ensure that if the flag is observed set, the
> associated attr fields written before smp_wmb() + set_bit() are
> also visible.
> 
> Writers keep smp_wmb() + set_bit() since no release bitop exists.
> 
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Assisted-by: DeepSeek:DeepSeek-V3
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902074805.398540-1-ruanjinjie@huawei.com?part=5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 3/8] fs: aio: Use acquire/release for ring->tail publication
  2026-09-02  7:48 ` [PATCH v3 3/8] fs: aio: Use acquire/release for ring->tail publication Jinjie Ruan
@ 2026-09-02  7:57   ` sashiko-bot
  0 siblings, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-09-02  7:57 UTC (permalink / raw)
  To: Jinjie Ruan; +Cc: tytso, linux-ext4

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The commit message claims to replace `WRITE_ONCE()` and `READ_ONCE()` which do not exist in the baseline code.
--

commit 8b8ddb17380f4323933c3731f5ced979ef864fa3
Author: Jinjie Ruan <ruanjinjie@huawei.com>

fs: aio: Use acquire/release for ring->tail publication

This commit replaces the explicit write and read memory barriers for
ring->tail with smp_store_release() and smp_load_acquire() in the aio
completion and read event paths. It aims to clarify the publish/subscribe
pattern and optimize for architectures with native acquire/release
instructions.

> Replace the smp_wmb() + WRITE_ONCE(ring->tail) and READ_ONCE(ring->tail)
> + smp_rmb() barrier pair with smp_store_release()/smp_load_acquire()
> on `ring->tail`.

[Severity: Medium]
Does this commit message accurately reflect the previous state of the code?

The message explicitly claims to replace WRITE_ONCE(ring->tail) and
READ_ONCE(ring->tail). However, the baseline code only used plain assignments
as seen in the diff below.

> diff --git a/fs/aio.c b/fs/aio.c
> index ebdb0e5b95fd9..a6ec7c51ac456 100644
> --- a/fs/aio.c
> +++ b/fs/aio.c
> @@ -1206,13 +1206,12 @@ static void aio_complete(struct aio_kiocb *iocb)
>  	/* after flagging the request as done, we
>  	 * must never even look at it again
>  	 */
> -	smp_wmb();	/* make event visible before updating tail */
> -
>  	ctx->tail = tail;
>  
>  	ring = folio_address(ctx->ring_folios[0]);
>  	head = ring->head;
> -	ring->tail = tail;
> +	/* Make event visible before updating tail */
> +	smp_store_release(&ring->tail, tail);
>  	flush_dcache_folio(ctx->ring_folios[0]);

[Severity: Medium]
Could the commit message be updated to clarify that this patch also fixes the
missing WRITE_ONCE() annotation?

The baseline code here in fs/aio.c:aio_complete() performed a plain write
with "ring->tail = tail;" rather than using WRITE_ONCE() as claimed.

[ ... ]

> @@ -1288,13 +1287,12 @@ static long aio_read_events_ring(struct kioctx *ctx,
>  	/* Access to ->ring_folios here is protected by ctx->ring_lock. */
>  	ring = folio_address(ctx->ring_folios[0]);
>  	head = ring->head;
> -	tail = ring->tail;
> -
>  	/*
>  	 * Ensure that once we've read the current tail pointer, that
>  	 * we also see the events that were stored up to the tail.
> +	 * Pairs with smp_store_release() in aio_complete().
>  	 */
> -	smp_rmb();
> +	tail = smp_load_acquire(&ring->tail);

[Severity: Medium]
Similarly, could the commit message note that this fixes a missing
READ_ONCE() annotation?

The baseline code here in fs/aio.c:aio_read_events_ring() used a plain read
with "tail = ring->tail;" instead of the claimed READ_ONCE().

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902074805.398540-1-ruanjinjie@huawei.com?part=3

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 6/8] super: Use acquire for SB_BORN check in super_cache_count()
  2026-09-02  7:48 ` [PATCH v3 6/8] super: Use acquire for SB_BORN check in super_cache_count() Jinjie Ruan
@ 2026-09-02  7:58   ` sashiko-bot
  0 siblings, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-09-02  7:58 UTC (permalink / raw)
  To: Jinjie Ruan; +Cc: tytso, linux-ext4

> The active SB_BORN check in super_cache_count() pairs with the
> smp_store_release() in super_wake() when publishing a newly initialized
> superblock.
> 
> Replace the historical independent smp_rmb() barrier with an acquire load
> on sb->s_flags via super_flags(). This expresses the publish-subscribe
> pattern more clearly and allows weakly-ordered architectures like arm64
> to utilize efficient native instructions (e.g., LDAR) instead of a full
> one-way barrier.
> 
> Also remove the outdated memory barrier comment in super_cache_count(),
> as the underlying super_flags() implementation already self-documents
> the matched smp_store_release() in super_wake().
> 
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Assisted-by: Gemini:Gemini-3.1
> Assisted-by: DeepSeek:DeepSeek-V3
> Reviewed-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902074805.398540-1-ruanjinjie@huawei.com?part=6


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 8/8] ext4: Convert group-count barrier protocol to acquire/release
  2026-09-02  7:48 ` [PATCH v3 8/8] ext4: Convert group-count barrier protocol to acquire/release Jinjie Ruan
@ 2026-09-02  7:58   ` sashiko-bot
  0 siblings, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-09-02  7:58 UTC (permalink / raw)
  To: Jinjie Ruan; +Cc: linux-ext4, tytso

> During an online resize, reading s_groups_count and s_blockfile_groups
> requires strict ordering against subsequent initialized block group
> metadata.
> 
> Replace the historical smp_wmb()/smp_rmb() pairs with smp_store_release()
> and smp_load_acquire(). This formalizes the publish-subscribe pattern
> and allows weakly-ordered architectures (e.g., arm64) to utilize native
> STLR/LDAR instructions instead of full DMB fences.
> 
> Update the documentation in resize.c and ext4.h accordingly.
> 
> Cc: "Theodore Ts'o" <tytso@mit.edu>
> Cc: Andreas Dilger <adilger.kernel@dilger.ca>
> Cc: Baokun Li <libaokun@linux.alibaba.com>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Ojaswin Mujoo <ojaswin@linux.ibm.com>
> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
> Cc: Zhang Yi <yi.zhang@huawei.com>
> Assisted-by: Gemini:Gemini-3.1
> Assisted-by: DeepSeek:DeepSeek-V3
> Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
> Reviewed-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902074805.398540-1-ruanjinjie@huawei.com?part=8


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 7/8] ext4: Fix out-of-bounds read in ext4_get_group_info()
  2026-09-02  7:48 ` [PATCH v3 7/8] ext4: Fix out-of-bounds read in ext4_get_group_info() Jinjie Ruan
@ 2026-09-02  8:01   ` sashiko-bot
  0 siblings, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-09-02  8:01 UTC (permalink / raw)
  To: Jinjie Ruan; +Cc: linux-ext4, tytso

> A plain read of s_groups_count in ext4_get_group_info() allows CPU
> load-load reordering. On weak memory models, speculative prefetch of
> s_group_info prior to the boundary check could lead to an out-of-bounds
> read if a concurrent online resize expands the array and increments
> s_groups_count.
> 
> The data race occurs between the ioctl configuration path (holding the
> resize lock via ext4_resize_begin) and the lockless metadata lookup path:
> 
>    CPU 0 (Writer, Resize Lock)                CPU 1 (Reader, Lockless)
>    ---------------------------                ------------------------
>    ext4_ioctl()
>      [EXT4_IOC_GROUP_ADD]
>      ext4_ioctl_group_add()
>        ext4_resize_begin() // Takes lock
> [ ... ]
> Fixes: 5354b2af3406 ("ext4: allow ext4_get_group_info() to fail")
> Link: https://sashiko.dev/#/patchset/20260825095422.3166067-1-ruanjinjie%40huawei.com
> Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
> Reviewed-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902074805.398540-1-ruanjinjie@huawei.com?part=7


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 1/8] user_namespace: Use acquire/release for nr_extents synchronization
  2026-09-02  7:47 ` [PATCH v3 1/8] user_namespace: Use acquire/release for nr_extents synchronization Jinjie Ruan
  2026-09-02  7:53   ` sashiko-bot
@ 2026-09-02 10:09   ` Bradley Morgan
  1 sibling, 0 replies; 18+ messages in thread
From: Bradley Morgan @ 2026-09-02 10:09 UTC (permalink / raw)
  To: ruanjinjie
  Cc: adilger.kernel, akpm, andriy.shevchenko, bcrl, brauner, jack,
	kees, libaokun, linux-aio, linux-ext4, linux-fsdevel,
	linux-kernel, linux, ojaswin, pmladek, ritesh.list, rostedt,
	senozhatsky, sforshee, tglx, tytso, viro, yi.zhang

On 2 September 2026 08:47:58 BST, Jinjie Ruan <ruanjinjie@huawei.com>
wrote:
>Replace smp_wmb()/smp_rmb() with smp_store_release()/smp_load_acquire()
>when publishing and consuming `nr_extents`. This expresses the
>publish/subscribe pattern more clearly and allows architectures with
>native acquire/release instructions (e.g. arm64's STLR/LDAR) to avoid
>the cost of full one-way barriers (DMB ISHST/ISHLD).
>
>No functional change intended.
>
>Cc: Alexander Viro <viro@zeniv.linux.org.uk>
>Cc: Christian Brauner <brauner@kernel.org>
>Cc: Jan Kara <jack@suse.cz>
>Cc: Seth Forshee <sforshee@kernel.org>
>Cc: Kees Cook <kees@kernel.org>
>Cc: Aleksa Sarai <cyphar@cyphar.com>
>Assisted-by: DeepSeek:DeepSeek-V3

LGTM, thanks

Reviewed-by: Bradley Morgan <brads@mainlining.org>


>Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
>---
>v2:
>- Add missing load replace in copy_mnt_idmap()
>---
> fs/mnt_idmapping.c      |  5 ++---
> kernel/user_namespace.c | 24 +++++++++++++-----------
> 2 files changed, 15 insertions(+), 14 deletions(-)
>
>diff --git a/fs/mnt_idmapping.c b/fs/mnt_idmapping.c
>index cb61fbdb52e9..612b266ab3da 100644
>--- a/fs/mnt_idmapping.c
>+++ b/fs/mnt_idmapping.c
>@@ -219,10 +219,9 @@ EXPORT_SYMBOL_GPL(vfsgid_in_group_p);
> static int copy_mnt_idmap(struct uid_gid_map *map_from,
> 			  struct uid_gid_map *map_to)
> {
>+	/* Pairs with smp_store_release() in map_write(). */
>+	u32 nr_extents = smp_load_acquire(&map_from->nr_extents);
> 	struct uid_gid_extent *forward, *reverse;
>-	u32 nr_extents = READ_ONCE(map_from->nr_extents);
>-	/* Pairs with smp_wmb() when writing the idmapping. */
>-	smp_rmb();
> 
> 	/*
> 	 * Don't blindly copy @map_to into @map_from if nr_extents is
>diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
>index 0bed462e9b2a..576b667a8813 100644
>--- a/kernel/user_namespace.c
>+++ b/kernel/user_namespace.c
>@@ -317,9 +317,9 @@ map_id_range_down_base(unsigned extents, struct uid_gid_map *map, u32 id, u32 co
> 
> static u32 map_id_range_down(struct uid_gid_map *map, u32 id, u32 count)
> {
>+	/* Pairs with smp_store_release() in map_write(). */
>+	unsigned int extents = smp_load_acquire(&map->nr_extents);
> 	struct uid_gid_extent *extent;
>-	unsigned extents = map->nr_extents;
>-	smp_rmb();
> 
> 	if (extents <= UID_GID_MAP_MAX_BASE_EXTENTS)
> 		extent = map_id_range_down_base(extents, map, id, count);
>@@ -383,9 +383,9 @@ map_id_range_up_max(unsigned extents, struct uid_gid_map *map, u32 id, u32 count
> 
> u32 map_id_range_up(struct uid_gid_map *map, u32 id, u32 count)
> {
>+	/* Pairs with smp_store_release() in map_write(). */
>+	unsigned int extents = smp_load_acquire(&map->nr_extents);
> 	struct uid_gid_extent *extent;
>-	unsigned extents = map->nr_extents;
>-	smp_rmb();
> 
> 	if (extents <= UID_GID_MAP_MAX_BASE_EXTENTS)
> 		extent = map_id_range_up_base(extents, map, id, count);
>@@ -676,9 +676,9 @@ static int projid_m_show(struct seq_file *seq, void *v)
> static void *m_start(struct seq_file *seq, loff_t *ppos,
> 		     struct uid_gid_map *map)
> {
>+	/* Pairs with smp_store_release() in map_write(). */
>+	unsigned int extents = smp_load_acquire(&map->nr_extents);
> 	loff_t pos = *ppos;
>-	unsigned extents = map->nr_extents;
>-	smp_rmb();
> 
> 	if (pos >= extents)
> 		return NULL;
>@@ -967,9 +967,11 @@ static ssize_t map_write(struct file *file, const char __user *buf,
> 	 * desired behavior is to see the values of the extents that
> 	 * were written before the count of the extents.
> 	 *
>-	 * To achieve this smp_wmb() is used on guarantee the write
>-	 * order and smp_rmb() is guaranteed that we don't have crazy
>-	 * architectures returning stale data.
>+	 * The nr_extents field is the publish point for the extent
>+	 * data.  Writers use smp_store_release() to ensure all extent
>+	 * data is visible before nr_extents is updated.  Readers use
>+	 * smp_load_acquire() to ensure they see a consistent view of
>+	 * the extent data when reading nr_extents.
> 	 */
> 	mutex_lock(&userns_state_mutex);
> 
>@@ -1098,8 +1100,8 @@ static ssize_t map_write(struct file *file, const char __user *buf,
> 		map->forward = new_map.forward;
> 		map->reverse = new_map.reverse;
> 	}
>-	smp_wmb();
>-	map->nr_extents = new_map.nr_extents;
>+	/* Pairs with smp_load_acquire() in map_id_range_{up,down}() and m_start(). */
>+	smp_store_release(&map->nr_extents, new_map.nr_extents);
> 
> 	*ppos = count;
> 	ret = count;
>

--- Thanks!
https://lore.kernel.org/all/EE579805-42F2-4C58-B752-F28779EEB717@grrlz.net/

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2026-09-02 10:10 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02  7:47 [PATCH v3 0/8] Convert barrier pairs to acquire/release for better performance Jinjie Ruan
2026-09-02  7:47 ` [PATCH v3 1/8] user_namespace: Use acquire/release for nr_extents synchronization Jinjie Ruan
2026-09-02  7:53   ` sashiko-bot
2026-09-02 10:09   ` Bradley Morgan
2026-09-02  7:47 ` [PATCH v3 2/8] lib/vsprintf: Use acquire/release for ptr_key publication Jinjie Ruan
2026-09-02  7:52   ` sashiko-bot
2026-09-02  7:48 ` [PATCH v3 3/8] fs: aio: Use acquire/release for ring->tail publication Jinjie Ruan
2026-09-02  7:57   ` sashiko-bot
2026-09-02  7:48 ` [PATCH v3 4/8] fs: Use acquire/release for fdtable resize synchronization Jinjie Ruan
2026-09-02  7:53   ` sashiko-bot
2026-09-02  7:48 ` [PATCH v3 5/8] pidfs: Use test_bit_acquire() for attr flag tests Jinjie Ruan
2026-09-02  7:55   ` sashiko-bot
2026-09-02  7:48 ` [PATCH v3 6/8] super: Use acquire for SB_BORN check in super_cache_count() Jinjie Ruan
2026-09-02  7:58   ` sashiko-bot
2026-09-02  7:48 ` [PATCH v3 7/8] ext4: Fix out-of-bounds read in ext4_get_group_info() Jinjie Ruan
2026-09-02  8:01   ` sashiko-bot
2026-09-02  7:48 ` [PATCH v3 8/8] ext4: Convert group-count barrier protocol to acquire/release Jinjie Ruan
2026-09-02  7:58   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox