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>
This commit is contained in:
Shakeel Butt 2026-03-10 18:00:59 -07:00 committed by Tejun Heo
parent 5b30afc20b
commit 05070cd654

View File

@ -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);