mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 23:22:31 +02:00
kernfs: switch global kernfs_idr_lock to per-fs lock
The kernfs implementation has big lock granularity(kernfs_idr_lock) so every kernfs-based(e.g., sysfs, cgroup) fs are able to compete the lock. This patch switches the global kernfs_idr_lock to per-fs lock, which put the spinlock into kernfs_root. Signed-off-by: Jinliang Zheng <alexjlzheng@tencent.com> Acked-by: Tejun Heo <tj@kernel.org> Link: https://lore.kernel.org/r/20250415153659.14950-2-alexjlzheng@tencent.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2806c6b8f3
commit
cec59c440a
|
|
@ -27,7 +27,6 @@ DEFINE_RWLOCK(kernfs_rename_lock); /* kn->parent and ->name */
|
|||
*/
|
||||
static DEFINE_SPINLOCK(kernfs_pr_cont_lock);
|
||||
static char kernfs_pr_cont_buf[PATH_MAX]; /* protected by pr_cont_lock */
|
||||
static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */
|
||||
|
||||
#define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb)
|
||||
|
||||
|
|
@ -584,9 +583,9 @@ void kernfs_put(struct kernfs_node *kn)
|
|||
if (kernfs_type(kn) == KERNFS_LINK)
|
||||
kernfs_put(kn->symlink.target_kn);
|
||||
|
||||
spin_lock(&kernfs_idr_lock);
|
||||
spin_lock(&root->kernfs_idr_lock);
|
||||
idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
|
||||
spin_unlock(&kernfs_idr_lock);
|
||||
spin_unlock(&root->kernfs_idr_lock);
|
||||
|
||||
call_rcu(&kn->rcu, kernfs_free_rcu);
|
||||
|
||||
|
|
@ -639,13 +638,13 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
|
|||
goto err_out1;
|
||||
|
||||
idr_preload(GFP_KERNEL);
|
||||
spin_lock(&kernfs_idr_lock);
|
||||
spin_lock(&root->kernfs_idr_lock);
|
||||
ret = idr_alloc_cyclic(&root->ino_idr, kn, 1, 0, GFP_ATOMIC);
|
||||
if (ret >= 0 && ret < root->last_id_lowbits)
|
||||
root->id_highbits++;
|
||||
id_highbits = root->id_highbits;
|
||||
root->last_id_lowbits = ret;
|
||||
spin_unlock(&kernfs_idr_lock);
|
||||
spin_unlock(&root->kernfs_idr_lock);
|
||||
idr_preload_end();
|
||||
if (ret < 0)
|
||||
goto err_out2;
|
||||
|
|
@ -681,9 +680,9 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
|
|||
return kn;
|
||||
|
||||
err_out3:
|
||||
spin_lock(&kernfs_idr_lock);
|
||||
spin_lock(&root->kernfs_idr_lock);
|
||||
idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
|
||||
spin_unlock(&kernfs_idr_lock);
|
||||
spin_unlock(&root->kernfs_idr_lock);
|
||||
err_out2:
|
||||
kmem_cache_free(kernfs_node_cache, kn);
|
||||
err_out1:
|
||||
|
|
@ -989,6 +988,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
|
|||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
idr_init(&root->ino_idr);
|
||||
spin_lock_init(&root->kernfs_idr_lock);
|
||||
init_rwsem(&root->kernfs_rwsem);
|
||||
init_rwsem(&root->kernfs_iattr_rwsem);
|
||||
init_rwsem(&root->kernfs_supers_rwsem);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ struct kernfs_root {
|
|||
|
||||
/* private fields, do not use outside kernfs proper */
|
||||
struct idr ino_idr;
|
||||
spinlock_t kernfs_idr_lock; /* root->ino_idr */
|
||||
u32 last_id_lowbits;
|
||||
u32 id_highbits;
|
||||
struct kernfs_syscall_ops *syscall_ops;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user