Skip to content

Commit 4ef420b

Browse files
shakeelbhtejun
authored andcommitted
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 <[email protected]> Signed-off-by: Shakeel Butt <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent 4616120 commit 4ef420b

2 files changed

Lines changed: 9 additions & 16 deletions

File tree

include/linux/cgroup-defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ struct cgroup_file {
167167
struct kernfs_node *kn;
168168
unsigned long notified_at;
169169
struct timer_list notify_timer;
170+
spinlock_t lock;
170171
};
171172

172173
/*

kernel/cgroup/cgroup.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,6 @@ static bool cgroup_debug __read_mostly;
9999
*/
100100
static DEFINE_SPINLOCK(cgroup_idr_lock);
101101

102-
/*
103-
* Protects cgroup_file->kn for !self csses. It synchronizes notifications
104-
* against file removal/re-creation across css hiding.
105-
*/
106-
static DEFINE_SPINLOCK(cgroup_file_kn_lock);
107-
108102
DEFINE_PERCPU_RWSEM(cgroup_threadgroup_rwsem);
109103

110104
#define cgroup_assert_mutex_or_rcu_locked() \
@@ -1693,9 +1687,9 @@ static void cgroup_rm_file(struct cgroup *cgrp, const struct cftype *cft)
16931687
struct cgroup_subsys_state *css = cgroup_css(cgrp, cft->ss);
16941688
struct cgroup_file *cfile = (void *)css + cft->file_offset;
16951689

1696-
spin_lock_irq(&cgroup_file_kn_lock);
1690+
spin_lock_irq(&cfile->lock);
16971691
WRITE_ONCE(cfile->kn, NULL);
1698-
spin_unlock_irq(&cgroup_file_kn_lock);
1692+
spin_unlock_irq(&cfile->lock);
16991693

17001694
timer_delete_sync(&cfile->notify_timer);
17011695
}
@@ -4373,10 +4367,8 @@ static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp,
43734367
struct cgroup_file *cfile = (void *)css + cft->file_offset;
43744368

43754369
timer_setup(&cfile->notify_timer, cgroup_file_notify_timer, 0);
4376-
4377-
spin_lock_irq(&cgroup_file_kn_lock);
4378-
WRITE_ONCE(cfile->kn, kn);
4379-
spin_unlock_irq(&cgroup_file_kn_lock);
4370+
spin_lock_init(&cfile->lock);
4371+
cfile->kn = kn;
43804372
}
43814373

43824374
return 0;
@@ -4645,13 +4637,13 @@ void cgroup_file_notify(struct cgroup_file *cfile)
46454637
return;
46464638
}
46474639

4648-
spin_lock_irqsave(&cgroup_file_kn_lock, flags);
4640+
spin_lock_irqsave(&cfile->lock, flags);
46494641
if (cfile->kn) {
46504642
kn = cfile->kn;
46514643
kernfs_get(kn);
46524644
WRITE_ONCE(cfile->notified_at, jiffies);
46534645
}
4654-
spin_unlock_irqrestore(&cgroup_file_kn_lock, flags);
4646+
spin_unlock_irqrestore(&cfile->lock, flags);
46554647

46564648
if (kn) {
46574649
kernfs_notify(kn);
@@ -4669,10 +4661,10 @@ void cgroup_file_show(struct cgroup_file *cfile, bool show)
46694661
{
46704662
struct kernfs_node *kn;
46714663

4672-
spin_lock_irq(&cgroup_file_kn_lock);
4664+
spin_lock_irq(&cfile->lock);
46734665
kn = cfile->kn;
46744666
kernfs_get(kn);
4675-
spin_unlock_irq(&cgroup_file_kn_lock);
4667+
spin_unlock_irq(&cfile->lock);
46764668

46774669
if (kn)
46784670
kernfs_show(kn, show);

0 commit comments

Comments
 (0)