diff options
| author | Shakeel Butt <shakeel.butt@linux.dev> | 2026-03-11 04:00:59 +0300 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2026-03-12 01:16:21 +0300 |
| commit | 05070cd654f38346d051b8c411faff196fa58880 (patch) | |
| tree | c3345845cbb27bca7b745d2d909991fb28eb2ca3 | |
| parent | 5b30afc20b3fea29b9beb83c6415c4ff06f774aa (diff) | |
| download | linux-05070cd654f38346d051b8c411faff196fa58880.tar.xz | |
cgroup: reduce cgroup_file_kn_lock hold time in cgroup_file_notify()
cgroup_file_notify() calls kernfs_notify() while holding the global
cgroup_file_kn_lock. kernfs_notify() does non-trivial work including
wake_up_interruptible() and acquisition of a second global spinlock
(kernfs_notify_lock), inflating the hold time.
Take a kernfs_get() reference under the lock and call kernfs_notify()
after dropping it, following the pattern from cgroup_file_show().
Reported-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
Signed-off-by: Tejun Heo <tj@kernel.org>
| -rw-r--r-- | kernel/cgroup/cgroup.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index cdc63be63f2c..26d8df60a59f 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -4632,6 +4632,7 @@ int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) void cgroup_file_notify(struct cgroup_file *cfile) { unsigned long flags; + struct kernfs_node *kn = NULL; spin_lock_irqsave(&cgroup_file_kn_lock, flags); if (cfile->kn) { @@ -4641,11 +4642,17 @@ void cgroup_file_notify(struct cgroup_file *cfile) if (time_in_range(jiffies, last, next)) { timer_reduce(&cfile->notify_timer, next); } else { - kernfs_notify(cfile->kn); + kn = cfile->kn; + kernfs_get(kn); cfile->notified_at = jiffies; } } spin_unlock_irqrestore(&cgroup_file_kn_lock, flags); + + if (kn) { + kernfs_notify(kn); + kernfs_put(kn); + } } EXPORT_SYMBOL_GPL(cgroup_file_notify); |
