proc_entry_rundown() waits for the last user of an entry with a completion on its stack that it points the entry at while it waits. That's a pointer in every struct proc_dir_entry for something that happens once in the life of an entry, if at all.
Wait on the count itself with wait_var_event() instead and let unuse_pde() wake the waiter with wake_up_var() when the count hits the bias. The waiters sleep on the hashed wait queues behind that, so procfs doesn't need a wait queue of its own for this, neither in the entry nor a global one. kernfs keeps one per root for the same thing, deactivate_waitq. Note that atomic_dec_return() is fully ordered, so the count is visible before wake_up_var() looks for waiters. No functional changes. Signed-off-by: Christian Brauner (Amutable) <[email protected]> --- fs/proc/inode.c | 7 +++---- fs/proc/internal.h | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 66a3688757dd..8795add1898d 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -25,6 +25,7 @@ #include <linux/slab.h> #include <linux/mount.h> #include <linux/bug.h> +#include <linux/wait_bit.h> #include "internal.h" @@ -203,7 +204,7 @@ static inline int use_pde(struct proc_dir_entry *pde) static void unuse_pde(struct proc_dir_entry *pde) { if (unlikely(atomic_dec_return(&pde->in_use) == BIAS)) - complete(pde->pde_unload_completion); + wake_up_var(&pde->in_use); } /* Pin an entry that can go away around a call into it, see use_pde(). */ @@ -266,11 +267,9 @@ static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo) void proc_entry_rundown(struct proc_dir_entry *de) { - DECLARE_COMPLETION_ONSTACK(c); /* Wait until all existing callers into module are done. */ - de->pde_unload_completion = &c; if (atomic_add_return(BIAS, &de->in_use) != BIAS) - wait_for_completion(&c); + wait_var_event(&de->in_use, atomic_read(&de->in_use) == BIAS); /* ->pde_openers list can't grow from now on. */ diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 6b61d09ac5e5..ab4d7bd1fb75 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -38,7 +38,6 @@ struct proc_dir_entry { struct list_head pde_openers; /* who did ->open, but not ->release */ /* protects ->pde_openers and all struct pde_opener instances */ spinlock_t pde_unload_lock; - struct completion *pde_unload_completion; const struct inode_operations *proc_iops; union { const struct proc_ops *proc_ops; -- 2.53.0
