From: Shakeel Butt Date: Wed, 11 Mar 2026 01:00:59 +0000 (-0700) Subject: cgroup: reduce cgroup_file_kn_lock hold time in cgroup_file_notify() X-Git-Tag: v7.1-rc1~164^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=05070cd654f38346d051b8c411faff196fa58880;p=thirdparty%2Fkernel%2Fstable.git 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 Signed-off-by: Shakeel Butt Signed-off-by: Tejun Heo --- diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index cdc63be63f2c7..26d8df60a59fa 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);