From nobody Wed Apr 8 03:07:03 2026 Received: from out-174.mta0.migadu.com (out-174.mta0.migadu.com [91.218.175.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4D5235FF57 for ; Wed, 11 Mar 2026 01:01:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773190876; cv=none; b=WVAlkDaES4oi0s3wSa2YxNdlk8ImWqwQdf0tpm5t/YYDZ0R93pfZM2F8yws13+IMSz/tWmMFnC4IYW9yD/sd965CM3xrHHDtcGQAH3GDa9owJcQ1/G2ME2Eb2nAFLyD2Bao2NNtYIlA5CG0K6Iqnym9EpWlADnI0Fh+lYt1Us2Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773190876; c=relaxed/simple; bh=CeiVAzQ8H3v9HU5U+4twZa9/8jKcb88Q/jIDoZ8McoA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PTEegqa3cqs7U4tASjvR3U1baG8PofmrsSoZrS7hUhhYQtb6SLl1mgVKlghDMPti7izt8sHXuYbm+TOoXud/LE+lBt2tM6CkqOEo8UcdGDvXB+iCCX1/LEBmcRHnxdJ6yDwGzAWfg7bV4kjF92PN2d4uQPvSxu02MVgmHX3lqoY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=mENMEn6+; arc=none smtp.client-ip=91.218.175.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="mENMEn6+" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1773190872; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qk+QKL+WWCN38YTC4yYy3ziupLEe6KfdX1avXXt55Pw=; b=mENMEn6+BnsiU6XV1NWHpmL1SS60MUkAa0TYha8EuJ+HcpgFsTh3g3+yZWm2JbmUzTk60x 5ZI+gQXEPI0d31SneW9hVgYfrQqPcyApjeizbDMb/HcJg1y90MgywSWKPH3aOHmYtdIuOp KI7aT5tKCeWCb35clfum+yD1/0FaEio= From: Shakeel Butt To: Tejun Heo Cc: Johannes Weiner , =?UTF-8?q?Michal=20Koutn=C3=BD?= , Chen Ridong , Jakub Kicinski , Meta kernel team , linux-mm@kvack.org, netdev@vger.kernel.org, cgroups@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/3] cgroup: reduce cgroup_file_kn_lock hold time in cgroup_file_notify() Date: Tue, 10 Mar 2026 18:00:59 -0700 Message-ID: <20260311010101.3306366-2-shakeel.butt@linux.dev> In-Reply-To: <20260311010101.3306366-1-shakeel.butt@linux.dev> References: <20260311010101.3306366-1-shakeel.butt@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" 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 --- Changes since v1: - N/A kernel/cgroup/cgroup.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 7e99258e9090..b3fbeadb2b5a 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -4686,6 +4686,7 @@ int cgroup_add_legacy_cftypes(struct cgroup_subsys *s= s, struct cftype *cfts) void cgroup_file_notify(struct cgroup_file *cfile) { unsigned long flags; + struct kernfs_node *kn =3D NULL; =20 spin_lock_irqsave(&cgroup_file_kn_lock, flags); if (cfile->kn) { @@ -4695,11 +4696,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 =3D cfile->kn; + kernfs_get(kn); cfile->notified_at =3D jiffies; } } spin_unlock_irqrestore(&cgroup_file_kn_lock, flags); + + if (kn) { + kernfs_notify(kn); + kernfs_put(kn); + } } EXPORT_SYMBOL_GPL(cgroup_file_notify); =20 --=20 2.52.0 From nobody Wed Apr 8 03:07:03 2026 Received: from out-182.mta0.migadu.com (out-182.mta0.migadu.com [91.218.175.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 58EBB36E46E for ; Wed, 11 Mar 2026 01:01:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773190878; cv=none; b=IDjsP7AoRB2OI5qrul+i7O53CaN3vV2kq3z2TyAJylUQiW86+vNCl2SUpL1PGUg20xRbdyypNOatbehd4k7CIEel86y8shGHJhwYDu7TwO8ONeubg9SYAHp6wWOKUicrqa+99KD9gyje90NpY8b2wp3dPCKJjbNncUzC19pLeLg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773190878; c=relaxed/simple; bh=Cj6aYpBIjzHQp9dQbgNhURSsAIaiBqiBxPXxNoGgK5Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u6gl6Ib7KV07peNE/umqudvEApP7PdCJ2S4U2i278byD7IX4KQYvpVCGd6r3nyzw2A0JenoUqnVOYCm5xHLo/GFrQDVOWteTCbwGWin5DUdvN3sj7fnrJ8Ziucb5hFiXCgmDRwwwoVKuueOYLNnbLcqakkH7oDl4IjHsv8Z7koQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Ccsx1/kW; arc=none smtp.client-ip=91.218.175.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Ccsx1/kW" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1773190875; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ql30l3PkbeNcbzr2KL87n3zGyPvc/RHjLKkGfbTuIH0=; b=Ccsx1/kWEQE637Iz9fq15VANKbX+Sc52j5gJqkyyS8WiTnvG1rt0Nq26WNuowFqsaeVz5e TVv7q7ZfgqfBPvuvsPAIWVAO0My4sYJy6kLqoP5o/4+GC0kpOqROj3vc/aHkuK1lY3OYYT wOsJX6uvUs1m9KF6WlfWhSG4VIhvuQI= From: Shakeel Butt To: Tejun Heo Cc: Johannes Weiner , =?UTF-8?q?Michal=20Koutn=C3=BD?= , Chen Ridong , Jakub Kicinski , Meta kernel team , linux-mm@kvack.org, netdev@vger.kernel.org, cgroups@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/3] cgroup: add lockless fast-path checks to cgroup_file_notify() Date: Tue, 10 Mar 2026 18:01:00 -0700 Message-ID: <20260311010101.3306366-3-shakeel.butt@linux.dev> In-Reply-To: <20260311010101.3306366-1-shakeel.butt@linux.dev> References: <20260311010101.3306366-1-shakeel.butt@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Add lockless checks before acquiring cgroup_file_kn_lock: 1. READ_ONCE(cfile->kn) NULL check to skip torn-down files. 2. READ_ONCE(cfile->notified_at) rate-limit check to skip when within the notification interval. If within the interval, arm the deferred timer via timer_reduce() and confirm it is pending before returning -- if the timer fired in between, fall through to the lock path so the notification is not lost. Both checks have safe error directions -- a stale read can only cause unnecessary lock acquisition, never a missed notification. The critical section is simplified to just taking a kernfs_get() reference and updating notified_at. Annotate cfile->kn and cfile->notified_at write sites with WRITE_ONCE() to pair with the lockless readers. Reported-by: Jakub Kicinski Signed-off-by: Shakeel Butt --- Changes since v1: - Moves the timer arming and rate limiting out of lock. kernel/cgroup/cgroup.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index b3fbeadb2b5a..b00f4c3242e0 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -1749,7 +1749,7 @@ static void cgroup_rm_file(struct cgroup *cgrp, const= struct cftype *cft) struct cgroup_file *cfile =3D (void *)css + cft->file_offset; =20 spin_lock_irq(&cgroup_file_kn_lock); - cfile->kn =3D NULL; + WRITE_ONCE(cfile->kn, NULL); spin_unlock_irq(&cgroup_file_kn_lock); =20 timer_delete_sync(&cfile->notify_timer); @@ -4429,7 +4429,7 @@ static int cgroup_add_file(struct cgroup_subsys_state= *css, struct cgroup *cgrp, timer_setup(&cfile->notify_timer, cgroup_file_notify_timer, 0); =20 spin_lock_irq(&cgroup_file_kn_lock); - cfile->kn =3D kn; + WRITE_ONCE(cfile->kn, kn); spin_unlock_irq(&cgroup_file_kn_lock); } =20 @@ -4685,21 +4685,25 @@ int cgroup_add_legacy_cftypes(struct cgroup_subsys = *ss, struct cftype *cfts) */ void cgroup_file_notify(struct cgroup_file *cfile) { - unsigned long flags; + unsigned long flags, last, next; struct kernfs_node *kn =3D NULL; =20 + if (!READ_ONCE(cfile->kn)) + return; + + last =3D READ_ONCE(cfile->notified_at); + next =3D last + CGROUP_FILE_NOTIFY_MIN_INTV; + if (time_in_range(jiffies, last, next)) { + timer_reduce(&cfile->notify_timer, next); + if (timer_pending(&cfile->notify_timer)) + return; + } + spin_lock_irqsave(&cgroup_file_kn_lock, flags); if (cfile->kn) { - unsigned long last =3D cfile->notified_at; - unsigned long next =3D last + CGROUP_FILE_NOTIFY_MIN_INTV; - - if (time_in_range(jiffies, last, next)) { - timer_reduce(&cfile->notify_timer, next); - } else { - kn =3D cfile->kn; - kernfs_get(kn); - cfile->notified_at =3D jiffies; - } + kn =3D cfile->kn; + kernfs_get(kn); + WRITE_ONCE(cfile->notified_at, jiffies); } spin_unlock_irqrestore(&cgroup_file_kn_lock, flags); =20 --=20 2.52.0 From nobody Wed Apr 8 03:07:03 2026 Received: from out-172.mta0.migadu.com (out-172.mta0.migadu.com [91.218.175.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1110536F437 for ; Wed, 11 Mar 2026 01:01:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773190882; cv=none; b=B4APd1nI0hcnmlV0QC6jQ3M0cM5uKlQsXADKRpGvjT2k9mkoMbYQsWO69yfodqz2kqyAYDi1Xf0K30PsZy6GUQxfCrVPfPGszNUAbt/C4VV5t/XRN8gb7MRUSnyUlyYB3bRur5iRQ8Rp029Jnput/hMi6IBlxy3M6WNCS/PF+Qc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773190882; c=relaxed/simple; bh=6uaML4bIG5BQHwy/29qZ13YY5ETzZT2ziuriWoIfeTY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=F+Re9Xjfvddypf+oImjdkKptEiivIsCtdpbgW1axQFCJyViE8nLDmDdwvNhCP4vcidY6evuCUyvV4XoF/zvIrR0KABS43akMpO0NBVPS/COEtvkV0G7Wfwcep/7EaPUwVWtpJEYAXjFbgFvBk6/OxhJRFxwYq/ZQvIwH3yTvFU8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=TAdFKhz4; arc=none smtp.client-ip=91.218.175.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="TAdFKhz4" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1773190878; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=K9HsfOrfS+eqleG7h8cZbUZvSAAorR+E1jNWHkvLrQs=; b=TAdFKhz4AGLvyBz1IQjH0d3LhD1RTXPiZ2TQ7EZzlcgkFQvEF434gIsHRJvYntgR8tsGMw /waxpyhhsTwNuPUNoJhbqy1ptgdIJ350DJKpO8K6NcG2plAibuoiWLvOwomc2307tPzKWU F6v7NInwpaK1M5+TnPFoRUzVIuHdlwo= From: Shakeel Butt To: Tejun Heo Cc: Johannes Weiner , =?UTF-8?q?Michal=20Koutn=C3=BD?= , Chen Ridong , Jakub Kicinski , Meta kernel team , linux-mm@kvack.org, netdev@vger.kernel.org, cgroups@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/3] cgroup: replace global cgroup_file_kn_lock with per-cgroup_file lock Date: Tue, 10 Mar 2026 18:01:01 -0700 Message-ID: <20260311010101.3306366-4-shakeel.butt@linux.dev> In-Reply-To: <20260311010101.3306366-1-shakeel.butt@linux.dev> References: <20260311010101.3306366-1-shakeel.butt@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" 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 Signed-off-by: Shakeel Butt --- Changes since v1: - N/A include/linux/cgroup-defs.h | 1 + kernel/cgroup/cgroup.c | 24 ++++++++---------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index bb92f5c169ca..ba26b5d05ce3 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -167,6 +167,7 @@ struct cgroup_file { struct kernfs_node *kn; unsigned long notified_at; struct timer_list notify_timer; + spinlock_t lock; }; =20 /* diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index b00f4c3242e0..d899bb2aef2f 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -107,12 +107,6 @@ static bool cgroup_debug __read_mostly; */ static DEFINE_SPINLOCK(cgroup_idr_lock); =20 -/* - * 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); =20 #define cgroup_assert_mutex_or_rcu_locked() \ @@ -1748,9 +1742,9 @@ static void cgroup_rm_file(struct cgroup *cgrp, const= struct cftype *cft) struct cgroup_subsys_state *css =3D cgroup_css(cgrp, cft->ss); struct cgroup_file *cfile =3D (void *)css + cft->file_offset; =20 - 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); =20 timer_delete_sync(&cfile->notify_timer); } @@ -4427,10 +4421,8 @@ static int cgroup_add_file(struct cgroup_subsys_stat= e *css, struct cgroup *cgrp, struct cgroup_file *cfile =3D (void *)css + cft->file_offset; =20 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 =3D kn; } =20 return 0; @@ -4699,13 +4691,13 @@ void cgroup_file_notify(struct cgroup_file *cfile) return; } =20 - spin_lock_irqsave(&cgroup_file_kn_lock, flags); + spin_lock_irqsave(&cfile->lock, flags); if (cfile->kn) { kn =3D 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); =20 if (kn) { kernfs_notify(kn); @@ -4723,10 +4715,10 @@ void cgroup_file_show(struct cgroup_file *cfile, bo= ol show) { struct kernfs_node *kn; =20 - spin_lock_irq(&cgroup_file_kn_lock); + spin_lock_irq(&cfile->lock); kn =3D cfile->kn; kernfs_get(kn); - spin_unlock_irq(&cgroup_file_kn_lock); + spin_unlock_irq(&cfile->lock); =20 if (kn) kernfs_show(kn, show); --=20 2.52.0