[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAGudoHH3HFDgu61S4VW2H2DXj1GMJzFRstTWhDx=jjHcb-ArwQ@mail.gmail.com>
Date: Thu, 5 Dec 2024 15:43:41 +0100
From: Mateusz Guzik <mjguzik@...il.com>
To: Al Viro <viro@...iv.linux.org.uk>
Cc: paulmck@...nel.org, brauner@...nel.org, jack@...e.cz,
linux-fsdevel@...r.kernel.org, torvalds@...ux-foundation.org,
edumazet@...gle.com, linux-kernel@...r.kernel.org
Subject: Re: [RFC PATCH] fs: elide the smp_rmb fence in fd_install()
On Thu, Dec 5, 2024 at 3:18 PM Al Viro <viro@...iv.linux.org.uk> wrote:
>
> On Thu, Dec 05, 2024 at 01:03:32PM +0100, Mateusz Guzik wrote:
> > void fd_install(unsigned int fd, struct file *file)
> > {
> > - struct files_struct *files = current->files;
> > + struct files_struct *files;
> > struct fdtable *fdt;
> >
> > if (WARN_ON_ONCE(unlikely(file->f_mode & FMODE_BACKING)))
> > return;
> >
> > + /*
> > + * Synchronized with expand_fdtable(), see that routine for an
> > + * explanation.
> > + */
> > rcu_read_lock_sched();
> > + files = READ_ONCE(current->files);
>
> What are you trying to do with that READ_ONCE()? current->files
> itself is *not* changed by any of that code; current->files->fdtab is.
To my understanding this is the idiomatic way of spelling out the
non-existent in Linux smp_consume_load, for the resize_in_progress
flag.
Anyway to elaborate I'm gunning for a setup where the code is
semantically equivalent to having a lock around the work.
Pretend ->resize_lock exists, then:
fd_install:
files = current->files;
read_lock(files->resize_lock);
fdt = rcu_dereference_sched(files->fdt);
rcu_assign_pointer(fdt->fd[fd], file);
read_unlock(files->resize_lock);
expand_fdtable:
write_lock(files->resize_lock);
[snip]
rcu_assign_pointer(files->fdt, new_fdt);
write_unlock(files->resize_lock);
Except rcu_read_lock_sched + appropriately fenced resize_in_progress +
synchronize_rcu do it.
--
Mateusz Guzik <mjguzik gmail.com>
Powered by blists - more mailing lists