linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Al Viro <viro@zeniv.linux.org.uk>
To: Max Kellermann <max.kellermann@ionos.com>
Cc: linux-fsdevel@vger.kernel.org,
	Christian Brauner <brauner@kernel.org>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 20/21] __dentry_kill(): new locking scheme
Date: Mon, 7 Jul 2025 18:29:56 +0100	[thread overview]
Message-ID: <20250707172956.GF1880847@ZenIV> (raw)
In-Reply-To: <CAKPOu+_Ktbp5OMZv77UfLRyRaqmK1kUpNHNd1C=J9ihvjWLDZg@mail.gmail.com>

On Mon, Jul 07, 2025 at 07:20:28PM +0200, Max Kellermann wrote:

> On Mon, Jul 7, 2025 at 7:04 PM Al Viro <viro@zeniv.linux.org.uk> wrote:
> > @@ -1478,6 +1444,8 @@ static enum d_walk_ret select_collect(void *_data, struct dentry *dentry)
> >         } else if (!dentry->d_lockref.count) {
> >                 to_shrink_list(dentry, &data->dispose);
> >                 data->found++;
> > +       } else if (dentry->d_lockref.count < 0) {
> > +               data->found++;
> >         }
> >         /*
> >          * We can return to the caller if we have found some (this
> 
> I have doubts about this part of your patch. (Warning: I don't really
> know what your patch is about.)
> 
> Why does this new check exist?
> (It checks for "dead" or "killed" entries, but why aren't you using
> __lockref_is_dead() here?)

What's the difference?  It checks for dentries currently still going through
->d_prune()/->d_iput()/->d_release().

> Actual problem why I found this: while debugging (yet another) Ceph
> bug, I found that a kworker is busy-looping inside
> shrink_dcache_parent(). Each iteration finds a dead/killed dentry,
> thus "found=true" and the loop keeps on looping forever, yet nothing
> ever gets done.
> It does this because a userspace process is trying to write to Ceph
> file, that write() system call invokes the shrinker (via
> filmap_add_folio() / memcg). The shrinker calls shrink_dentry_list(),
> __dentry_kill() - now that dentry is dead/killed, but it remains
> listed in the parent because the thread is stuck in ceph_evict_inode()
> / netfs_wait_for_outstanding_io().
> 
> I am seeing this because Ceph doesn't finish I/O on the inode, which
> causes the kworker to busy-loop forever without making any progress.
> But even if Ceph weren't as buggy as it is, there may still be some
> time waiting for the Ceph server, and that will always cause brief
> periods of busy-looping in the kworker, won't it?
> 
> I don't know how to solve this (I have no idea about the dcache,
> having opened its source for the first time today), but I wonder why
> select_collect() ever cares about dead/killed dentries. Removing that
> check seems like the obvious solution, but there must be a reason why
> you added it.

shrink_dcache_parent() is "evict everything that can be evicted in the
subtree"; no idea whether it's the right primitive for your usecase.

Note that these suckers *do* keep their ancestors pinned; as the result
we are, e.g., guaranteed sane ordering on RCU grace periods for their
freeing, etc.  One thing we definitely do not want is eviction of parent
started before its child is done with __dentry_kill()...

What are you using shrink_dcache_parent() for?

  reply	other threads:[~2025-07-07 17:29 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-24  6:02 [RFC][PATCHSET v3] simplifying fast_dput(), dentry_kill() et.al Al Viro
2023-11-24  6:04 ` [PATCH v3 01/21] switch nfsd_client_rmdir() to use of simple_recursive_removal() Al Viro
2023-11-24  6:04   ` [PATCH v3 02/21] coda_flag_children(): cope with dentries turning negative Al Viro
2023-11-24 21:22     ` Linus Torvalds
2023-11-24 22:58       ` Paul E. McKenney
2023-11-24  6:04   ` [PATCH v3 03/21] dentry: switch the lists of children to hlist Al Viro
2023-11-24  7:44     ` Amir Goldstein
2023-11-24  7:55       ` Al Viro
2023-11-24  8:02         ` Amir Goldstein
2023-11-24  6:04   ` [PATCH v3 04/21] centralize killing dentry from shrink list Al Viro
2023-11-24  6:04   ` [PATCH v3 05/21] shrink_dentry_list(): no need to check that dentry refcount is marked dead Al Viro
2023-11-24  6:04   ` [PATCH v3 06/21] fast_dput(): having ->d_delete() is not reason to delay refcount decrement Al Viro
2023-11-24  6:04   ` [PATCH v3 07/21] fast_dput(): handle underflows gracefully Al Viro
2023-11-24  6:04   ` [PATCH v3 08/21] fast_dput(): new rules for refcount Al Viro
2023-11-24  6:04   ` [PATCH v3 09/21] __dput_to_list(): do decrement of refcount in the callers Al Viro
2023-11-24  6:04   ` [PATCH v3 10/21] make retain_dentry() neutral with respect to refcounting Al Viro
2023-11-24  6:04   ` [PATCH v3 11/21] __dentry_kill(): get consistent rules for victim's refcount Al Viro
2023-11-24  6:04   ` [PATCH v3 12/21] dentry_kill(): don't bother with retain_dentry() on slow path Al Viro
2023-11-24  6:04   ` [PATCH v3 13/21] Call retain_dentry() with refcount 0 Al Viro
2023-11-24  6:04   ` [PATCH v3 14/21] fold the call of retain_dentry() into fast_dput() Al Viro
2023-11-24  6:04   ` [PATCH v3 15/21] don't try to cut corners in shrink_lock_dentry() Al Viro
2023-11-24  6:04   ` [PATCH v3 16/21] fold dentry_kill() into dput() Al Viro
2023-11-24  6:04   ` [PATCH v3 17/21] to_shrink_list(): call only if refcount is 0 Al Viro
2023-11-24  6:04   ` [PATCH v3 18/21] switch select_collect{,2}() to use of to_shrink_list() Al Viro
2023-11-24  6:04   ` [PATCH v3 19/21] d_prune_aliases(): use a shrink list Al Viro
2023-11-24  6:04   ` [PATCH v3 20/21] __dentry_kill(): new locking scheme Al Viro
2025-07-07 17:20     ` Max Kellermann
2025-07-07 17:29       ` Al Viro [this message]
2025-07-07 17:43         ` Max Kellermann
2025-07-07 18:00           ` Al Viro
2025-07-07 18:11             ` Max Kellermann
2025-07-07 19:31               ` Al Viro
2025-07-07 20:00                 ` Max Kellermann
2025-07-07 20:31                   ` Al Viro
2025-07-07 20:39                     ` Max Kellermann
2025-07-07 20:49                       ` Al Viro
2025-07-07 20:52                         ` Max Kellermann
2025-07-07 20:59                           ` Al Viro
2025-07-07 21:06                             ` Max Kellermann
2025-07-07 21:32                               ` Al Viro
2025-07-07 21:47                                 ` Max Kellermann
2025-07-07 22:19                                   ` Al Viro
2025-07-07 22:37                                     ` Al Viro
2025-07-08  4:45                                       ` Max Kellermann
2025-07-07 22:26       ` Al Viro
2023-11-24  6:04   ` [PATCH v3 21/21] retain_dentry(): introduce a trimmed-down lockless variant Al Viro
2023-11-24 21:28 ` [RFC][PATCHSET v3] simplifying fast_dput(), dentry_kill() et.al Linus Torvalds

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=20250707172956.GF1880847@ZenIV \
    --to=viro@zeniv.linux.org.uk \
    --cc=brauner@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=max.kellermann@ionos.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).