summaryrefslogtreecommitdiff
path: root/include/mtd/git@git.tavy.me:linux-stable.git
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2026-01-21 18:17:12 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2026-04-04 04:03:56 -0400
commit14a51045e10d3087b8374deef02a9d3a694132d6 (patch)
tree1a9e4b5aeb22f2f7025abc2f1b2ab250ccc5495c /include/mtd/git@git.tavy.me:linux-stable.git
parent5408c22b816f7012cc5ba80469389a088ab13663 (diff)
get rid of busy-waiting in shrink_dcache_tree()
If shrink_dcache_tree() runs into a potential victim that is already dying, it must wait for that dentry to go away. To avoid busy-waiting we need some object to wait on and a way for dentry_unlist() to see that we need to be notified. The obvious place for the object to wait on would be on our stack frame. We will store a pointer to that object (struct completion_list) in victim dentry; if there's more than one thread wanting to wait for the same dentry to finish dying, we'll have their instances linked into a list, with reference in dentry pointing to the head of that list. * new object - struct completion_list. A pair of struct completion and pointer to the next instance. That's what shrink_dcache_tree() will wait on if needed. * add a new member (->waiters, opaque pointer to struct completion_list) to struct dentry. It is defined for negative live dentries that are not in-lookup ones and it will remain NULL for almost all of them. It does not conflict with ->d_rcu (defined for killed dentries), ->d_alias (defined for positive dentries, all live) or ->d_in_lookup_hash (defined for in-lookup dentries, all live negative). That allows to colocate all four members. * make sure that all places where dentry enters the state where ->waiters is defined (live, negative, not-in-lookup) initialize ->waiters to NULL. * if select_collect2() runs into a dentry that is already dying, have its caller insert a local instance of struct completion_list into the head of the list hanging off dentry->waiters and wait for completion. * if dentry_unlist() sees non-NULL ->waiters, have it carefully walk through the completion_list instances in that list, calling complete() for each. For now struct completion_list is local to fs/dcache.c; it's obviously dentry-agnostic, and it can be trivially lifted into linux/completion.h if somebody finds a reason to do so... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include/mtd/git@git.tavy.me:linux-stable.git')
0 files changed, 0 insertions, 0 deletions