* [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
` (2 more replies)
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, 3 replies; 20+ 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] 20+ 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
2026-09-02 13:03 ` Andy Shevchenko
2 siblings, 0 replies; 20+ 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] 20+ 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
2026-09-02 13:03 ` Andy Shevchenko
2 siblings, 0 replies; 20+ 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] 20+ 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
@ 2026-09-02 13:03 ` Andy Shevchenko
2026-09-02 13:04 ` Andy Shevchenko
2 siblings, 1 reply; 20+ messages in thread
From: Andy Shevchenko @ 2026-09-02 13:03 UTC (permalink / raw)
To: Jinjie Ruan
Cc: bcrl, viro, brauner, jack, tytso, adilger.kernel, libaokun,
ojaswin, ritesh.list, yi.zhang, sforshee, akpm, pmladek, rostedt,
linux, senozhatsky, kees, tglx, linux-fsdevel, linux-aio,
linux-kernel, linux-ext4
On Wed, Sep 02, 2026 at 03:47:58PM +0800, Jinjie Ruan 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.
Please, locate Cc list...
> 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>o
...(all the above)...
> Assisted-by: DeepSeek:DeepSeek-V3
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
> ---
...somewhere here. It will have the same effect on the email thread and it will
unload the commit message from the unneeded noise.
> 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(-)
...
This comment applies to the whole series.
Also note, `b4 trailers` can handle that, you can keep the
---
Cc: ...
in the local Git. You can find some details in the subthread here
https://lore.kernel.org/lkml/20260123113708.416727-19-bigeasy@linutronix.de/
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 1/8] user_namespace: Use acquire/release for nr_extents synchronization
2026-09-02 13:03 ` Andy Shevchenko
@ 2026-09-02 13:04 ` Andy Shevchenko
0 siblings, 0 replies; 20+ messages in thread
From: Andy Shevchenko @ 2026-09-02 13:04 UTC (permalink / raw)
To: Jinjie Ruan
Cc: bcrl, viro, brauner, jack, tytso, adilger.kernel, libaokun,
ojaswin, ritesh.list, yi.zhang, sforshee, akpm, pmladek, rostedt,
linux, senozhatsky, kees, tglx, linux-fsdevel, linux-aio,
linux-kernel, linux-ext4
On Wed, Sep 02, 2026 at 04:03:23PM +0300, Andy Shevchenko wrote:
> On Wed, Sep 02, 2026 at 03:47:58PM +0800, Jinjie Ruan 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.
>
> Please, locate Cc list...
>
> > 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>o
>
> ...(all the above)...
Important remark: this is only about Cc, the regular tags have to be
in the commit message trailers (such as Reviewed-by).
> > Assisted-by: DeepSeek:DeepSeek-V3
> > Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
> > ---
>
> ...somewhere here. It will have the same effect on the email thread and it will
> unload the commit message from the unneeded noise.
>
> > 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(-)
>
> ...
>
> This comment applies to the whole series.
> Also note, `b4 trailers` can handle that, you can keep the
>
> ---
> Cc: ...
>
> in the local Git. You can find some details in the subthread here
> https://lore.kernel.org/lkml/20260123113708.416727-19-bigeasy@linutronix.de/
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ messages in thread