Skip to content

Commit cec59c4

Browse files
fatherMatrixgregkh
authored andcommitted
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>
1 parent 2806c6b commit cec59c4

File tree

2 files changed

+8
-7
lines changed

2 files changed

+8
-7
lines changed

fs/kernfs/dir.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ DEFINE_RWLOCK(kernfs_rename_lock); /* kn->parent and ->name */
2727
*/
2828
static DEFINE_SPINLOCK(kernfs_pr_cont_lock);
2929
static char kernfs_pr_cont_buf[PATH_MAX]; /* protected by pr_cont_lock */
30-
static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */
3130

3231
#define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb)
3332

@@ -584,9 +583,9 @@ void kernfs_put(struct kernfs_node *kn)
584583
if (kernfs_type(kn) == KERNFS_LINK)
585584
kernfs_put(kn->symlink.target_kn);
586585

587-
spin_lock(&kernfs_idr_lock);
586+
spin_lock(&root->kernfs_idr_lock);
588587
idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
589-
spin_unlock(&kernfs_idr_lock);
588+
spin_unlock(&root->kernfs_idr_lock);
590589

591590
call_rcu(&kn->rcu, kernfs_free_rcu);
592591

@@ -639,13 +638,13 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
639638
goto err_out1;
640639

641640
idr_preload(GFP_KERNEL);
642-
spin_lock(&kernfs_idr_lock);
641+
spin_lock(&root->kernfs_idr_lock);
643642
ret = idr_alloc_cyclic(&root->ino_idr, kn, 1, 0, GFP_ATOMIC);
644643
if (ret >= 0 && ret < root->last_id_lowbits)
645644
root->id_highbits++;
646645
id_highbits = root->id_highbits;
647646
root->last_id_lowbits = ret;
648-
spin_unlock(&kernfs_idr_lock);
647+
spin_unlock(&root->kernfs_idr_lock);
649648
idr_preload_end();
650649
if (ret < 0)
651650
goto err_out2;
@@ -681,9 +680,9 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
681680
return kn;
682681

683682
err_out3:
684-
spin_lock(&kernfs_idr_lock);
683+
spin_lock(&root->kernfs_idr_lock);
685684
idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
686-
spin_unlock(&kernfs_idr_lock);
685+
spin_unlock(&root->kernfs_idr_lock);
687686
err_out2:
688687
kmem_cache_free(kernfs_node_cache, kn);
689688
err_out1:
@@ -989,6 +988,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
989988
return ERR_PTR(-ENOMEM);
990989

991990
idr_init(&root->ino_idr);
991+
spin_lock_init(&root->kernfs_idr_lock);
992992
init_rwsem(&root->kernfs_rwsem);
993993
init_rwsem(&root->kernfs_iattr_rwsem);
994994
init_rwsem(&root->kernfs_supers_rwsem);

fs/kernfs/kernfs-internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct kernfs_root {
4040

4141
/* private fields, do not use outside kernfs proper */
4242
struct idr ino_idr;
43+
spinlock_t kernfs_idr_lock; /* root->ino_idr */
4344
u32 last_id_lowbits;
4445
u32 id_highbits;
4546
struct kernfs_syscall_ops *syscall_ops;

0 commit comments

Comments
 (0)