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). Assisted-by: DeepSeek:DeepSeek-V3 Signed-off-by: Jinjie Ruan --- 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