All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org
Cc: Alexander Viro <viro@zeniv.linux.org.uk>, Jan Kara <jack@suse.cz>,
	 Peter Zijlstra <peterz@infradead.org>,
	 "Paul E. McKenney" <paulmck@kernel.org>,
	 "Christian Brauner (Amutable)" <brauner@kernel.org>
Subject: [PATCH 5/5] Documentation: update the lock-free file lookup in files.rst
Date: Thu, 05 Nov 2026 14:18:09 +0100	[thread overview]
Message-ID: <20261105-work-file_ref-ordering-v1-5-8713f4876b7b@kernel.org> (raw)
In-Reply-To: <20261105-work-file_ref-ordering-v1-0-8713f4876b7b@kernel.org>

The lock-free lookup section of files.rst still sends readers to the
lookup_fdget_rcu() helpers that commit 8fd3395ec905 ("get rid of
...lookup...fdget_rcu() family") removed. And the SLAB_TYPESAFE_BY_RCU
paragraph still describes the reference as atomic_long_inc_not_zero()
and points to __files_get_rcu(), which doesn't exist, the lookup is
__fget_files_rcu(). Files have been using file_ref since commit
90ee6ed776c0 ("fs: port files to file_ref").

So point readers to fget() and friends and spell out what the lookup
does now: take the reference with file_ref_get(), reload the pointer,
compare against a copy the compiler can't see through and return the
reloaded pointer. Then say which orderings that rests on, the acquire
in file_ref_get(), the dependency on the reload and the full ordering
of file_ref_put(), and where they are documented and checked:
include/linux/file_ref.h and Documentation/litmus-tests/fs/.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
 Documentation/filesystems/files.rst | 48 +++++++++++++++++++++++--------------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/Documentation/filesystems/files.rst b/Documentation/filesystems/files.rst
index eb770f891b27..59536e62ed74 100644
--- a/Documentation/filesystems/files.rst
+++ b/Documentation/filesystems/files.rst
@@ -61,29 +61,32 @@ the fdtable structure -
 3. For any update to the fd table, files->file_lock must
    be held.
 
-4. To look up the file structure given an fd, a reader
-   must use either lookup_fdget_rcu() or files_lookup_fdget_rcu() APIs. These
-   take care of barrier requirements due to lock-free lookup.
+4. To look up the file structure given an fd, a reader must use one of
+   the fget() helpers: fget(), fget_raw(), fget_task(), fget_task_next()
+   or fdget() and friends. These take the reference and take care of
+   the barrier requirements of the lock-free lookup.
 
    An example::
 
 	struct file *file;
 
-	rcu_read_lock();
-	file = lookup_fdget_rcu(fd);
-	rcu_read_unlock();
+	file = fget(fd);
 	if (file) {
 		...
-                fput(file);
+		fput(file);
 	}
 	....
 
+   fdget() skips the reference when the file descriptor table isn't
+   shared, see the comment above __fget_light() for the rules that come
+   with that. Under files->file_lock a file can be looked up without a
+   reference with files_lookup_fd_locked() as long as the lock is held.
+
 5. Since both fdtable and file structures can be looked up
    lock-free, they must be installed using rcu_assign_pointer()
    API. If they are looked up lock-free, rcu_dereference()
    must be used. However it is advisable to use files_fdtable()
-   and lookup_fdget_rcu()/files_lookup_fdget_rcu() which take care of these
-   issues.
+   and the fget() helpers which take care of these issues.
 
 6. While updating, the fdtable pointer must be looked up while
    holding files->file_lock. If ->file_lock is dropped, then
@@ -105,15 +108,24 @@ the fdtable structure -
    Since locate_fd() can drop ->file_lock (and reacquire ->file_lock),
    the fdtable pointer (fdt) must be loaded after locate_fd().
 
-On newer kernels rcu based file lookup has been switched to rely on
-SLAB_TYPESAFE_BY_RCU instead of call_rcu(). It isn't sufficient anymore
-to just acquire a reference to the file in question under rcu using
-atomic_long_inc_not_zero() since the file might have already been
-recycled and someone else might have bumped the reference. In other
-words, callers might see reference count bumps from newer users. For
-this is reason it is necessary to verify that the pointer is the same
-before and after the reference count increment. This pattern can be seen
-in get_file_rcu() and __files_get_rcu().
+Files are allocated from a SLAB_TYPESAFE_BY_RCU cache since commit
+0ede61d8589c ("file: convert to SLAB_TYPESAFE_BY_RCU"). Freeing a file
+doesn't wait for a grace period anymore. The memory can be handed out
+again right away and only the type of the object is stable under
+rcu_read_lock(). So it isn't sufficient to take a reference on the file
+found in a descriptor slot. The file might have been closed, freed and
+recycled in the meantime and the reference lands on whoever owns the
+object now. The lock-free lookup in __fget_files_rcu() and
+__get_file_rcu() therefore:
+
+(1) loads the pointer from the slot and takes a reference with
+    file_ref_get(), which fails if the file is dead,
+
+(2) reloads the pointer and compares it against the earlier load, if they
+    differ the file was recycled and the reference is dropped again, and
+
+(3) returns the reloaded pointer so that everything the caller reads
+    from the file depends on the reload.
 
 In addition, it isn't possible to access or check fields in struct file
 without first acquiring a reference on it under rcu lookup. Not doing

-- 
2.53.0


      parent reply	other threads:[~2026-11-05 13:18 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 13:18 [PATCH 0/5] file: fix and document ordering for lockless fd lookup wrt to file_ref Christian Brauner
2026-11-05 13:18 ` [PATCH 1/5] file: depend on the reloaded pointer in __fget_files_rcu() Christian Brauner
2026-11-05 13:18 ` [PATCH 2/5] file_ref: use acquire ordering in file_ref_get() Christian Brauner
2026-11-05 13:18 ` [PATCH 3/5] file_ref: document why file_ref_put() stays fully ordered Christian Brauner
2026-11-05 13:18 ` [PATCH 4/5] Documentation/litmus-tests: add the file reference count tests Christian Brauner
2026-11-05 13:18 ` Christian Brauner [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261105-work-file_ref-ordering-v1-5-8713f4876b7b@kernel.org \
    --to=brauner@kernel.org \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.