aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorShakeel Butt <shakeel.butt@linux.dev>2026-03-10 18:01:01 -0700
committerTejun Heo <tj@kernel.org>2026-03-11 12:16:21 -1000
commit4ef420b3450026b56807e5d53001f80eb495403c (patch)
tree032a895c6628d08085f3bcd31a9e68a403fc4f84 /kernel
parent4616120fca7f6d48b4c640e3975352e451e9c2ce (diff)
cgroup: replace global cgroup_file_kn_lock with per-cgroup_file lock
Replace the global cgroup_file_kn_lock with a per-cgroup_file spinlock to eliminate cross-cgroup contention as it is not really protecting data shared between different cgroups. The lock is initialized in cgroup_add_file() alongside timer_setup(). No lock acquisition is needed during initialization since the cgroup directory is being populated under cgroup_mutex and no concurrent accessors exist at that point. Reported-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cgroup/cgroup.c24
1 files changed, 8 insertions, 16 deletions
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index d161bcaa68f1..6f58efeb9016 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -99,12 +99,6 @@ static bool cgroup_debug __read_mostly;
*/
static DEFINE_SPINLOCK(cgroup_idr_lock);
-/*
- * Protects cgroup_file->kn for !self csses. It synchronizes notifications
- * against file removal/re-creation across css hiding.
- */
-static DEFINE_SPINLOCK(cgroup_file_kn_lock);
-
DEFINE_PERCPU_RWSEM(cgroup_threadgroup_rwsem);
#define cgroup_assert_mutex_or_rcu_locked() \
@@ -1693,9 +1687,9 @@ static void cgroup_rm_file(struct cgroup *cgrp, const struct cftype *cft)
struct cgroup_subsys_state *css = cgroup_css(cgrp, cft->ss);
struct cgroup_file *cfile = (void *)css + cft->file_offset;
- spin_lock_irq(&cgroup_file_kn_lock);
+ spin_lock_irq(&cfile->lock);
WRITE_ONCE(cfile->kn, NULL);
- spin_unlock_irq(&cgroup_file_kn_lock);
+ spin_unlock_irq(&cfile->lock);
timer_delete_sync(&cfile->notify_timer);
}
@@ -4373,10 +4367,8 @@ static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp,
struct cgroup_file *cfile = (void *)css + cft->file_offset;
timer_setup(&cfile->notify_timer, cgroup_file_notify_timer, 0);
-
- spin_lock_irq(&cgroup_file_kn_lock);
- WRITE_ONCE(cfile->kn, kn);
- spin_unlock_irq(&cgroup_file_kn_lock);
+ spin_lock_init(&cfile->lock);
+ cfile->kn = kn;
}
return 0;
@@ -4645,13 +4637,13 @@ void cgroup_file_notify(struct cgroup_file *cfile)
return;
}
- spin_lock_irqsave(&cgroup_file_kn_lock, flags);
+ spin_lock_irqsave(&cfile->lock, flags);
if (cfile->kn) {
kn = cfile->kn;
kernfs_get(kn);
WRITE_ONCE(cfile->notified_at, jiffies);
}
- spin_unlock_irqrestore(&cgroup_file_kn_lock, flags);
+ spin_unlock_irqrestore(&cfile->lock, flags);
if (kn) {
kernfs_notify(kn);
@@ -4669,10 +4661,10 @@ void cgroup_file_show(struct cgroup_file *cfile, bool show)
{
struct kernfs_node *kn;
- spin_lock_irq(&cgroup_file_kn_lock);
+ spin_lock_irq(&cfile->lock);
kn = cfile->kn;
kernfs_get(kn);
- spin_unlock_irq(&cgroup_file_kn_lock);
+ spin_unlock_irq(&cfile->lock);
if (kn)
kernfs_show(kn, show);