Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Jinliang Zheng and committed by
Greg Kroah-Hartman
cec59c44 2806c6b8

+8 -7
+7 -7
fs/kernfs/dir.c
··· 27 27 */ 28 28 static DEFINE_SPINLOCK(kernfs_pr_cont_lock); 29 29 static char kernfs_pr_cont_buf[PATH_MAX]; /* protected by pr_cont_lock */ 30 - static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */ 31 30 32 31 #define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb) 33 32 ··· 583 584 if (kernfs_type(kn) == KERNFS_LINK) 584 585 kernfs_put(kn->symlink.target_kn); 585 586 586 - spin_lock(&kernfs_idr_lock); 587 + spin_lock(&root->kernfs_idr_lock); 587 588 idr_remove(&root->ino_idr, (u32)kernfs_ino(kn)); 588 - spin_unlock(&kernfs_idr_lock); 589 + spin_unlock(&root->kernfs_idr_lock); 589 590 590 591 call_rcu(&kn->rcu, kernfs_free_rcu); 591 592 ··· 638 639 goto err_out1; 639 640 640 641 idr_preload(GFP_KERNEL); 641 - spin_lock(&kernfs_idr_lock); 642 + spin_lock(&root->kernfs_idr_lock); 642 643 ret = idr_alloc_cyclic(&root->ino_idr, kn, 1, 0, GFP_ATOMIC); 643 644 if (ret >= 0 && ret < root->last_id_lowbits) 644 645 root->id_highbits++; 645 646 id_highbits = root->id_highbits; 646 647 root->last_id_lowbits = ret; 647 - spin_unlock(&kernfs_idr_lock); 648 + spin_unlock(&root->kernfs_idr_lock); 648 649 idr_preload_end(); 649 650 if (ret < 0) 650 651 goto err_out2; ··· 680 681 return kn; 681 682 682 683 err_out3: 683 - spin_lock(&kernfs_idr_lock); 684 + spin_lock(&root->kernfs_idr_lock); 684 685 idr_remove(&root->ino_idr, (u32)kernfs_ino(kn)); 685 - spin_unlock(&kernfs_idr_lock); 686 + spin_unlock(&root->kernfs_idr_lock); 686 687 err_out2: 687 688 kmem_cache_free(kernfs_node_cache, kn); 688 689 err_out1: ··· 988 989 return ERR_PTR(-ENOMEM); 989 990 990 991 idr_init(&root->ino_idr); 992 + spin_lock_init(&root->kernfs_idr_lock); 991 993 init_rwsem(&root->kernfs_rwsem); 992 994 init_rwsem(&root->kernfs_iattr_rwsem); 993 995 init_rwsem(&root->kernfs_supers_rwsem);
+1
fs/kernfs/kernfs-internal.h
··· 40 40 41 41 /* private fields, do not use outside kernfs proper */ 42 42 struct idr ino_idr; 43 + spinlock_t kernfs_idr_lock; /* root->ino_idr */ 43 44 u32 last_id_lowbits; 44 45 u32 id_highbits; 45 46 struct kernfs_syscall_ops *syscall_ops;