From nobody Fri Sep 25 12:05:33 2026 Received: from mta0.migadu.com (out-181.mta0.migadu.com [91.218.175.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B5C652F9D82 for ; Sun, 13 Sep 2026 02:15:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789265712; cv=none; b=YGbcZ9NKReUKQJgqn74vFTMNMwtq+zC0o2N2rMov+Fk6Gf8LVPdM/J88wgeOz+FL9ea39bgLYQQFb7to+UIT/w7zZQJwtpYwKpIJQ9zCViKgq/sbSdEReEHlcH7my31KznNXdeALo/yUwQZyHRuuHwdTsesoim91tBfvJMEjRQU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789265712; c=relaxed/simple; bh=lLMjhtX8mQSkcteJdNHfuS1BULHYOy4nyuYAaZWcCw8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KQQibXJk/UjOgUW4ubeGShrbWEfkI5mNqoL/ooOsRb8sY/EOVkEotEg50Rcvo1i59EWRutPsVgzBEmIIq8hLjTfBZyGkb4EBTVy1FZy5Q70hoLyIWpHmH+wYq6dehCB45yg4UOi6TpgfZTorudGQm2MKy2gmaVP/e1Si6WHZ4FU= 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=WfpdAdlW; arc=none smtp.client-ip=91.218.175.181 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="WfpdAdlW" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=lLMjhtX8mQSkcteJdNHfuS1BULHYOy4nyuYAaZWcCw8=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1789265708; v=1; x=1789870508; b=WfpdAdlWBBScYJQwkKUReOvuNHQFT9ZredA9hMe/pb65w2YpBmPzjhUpylw/0CCrT0XylETe VT+/bjsJQZEYBhBGcvXvo/Yrx8ClCXncJXj1AOLK9eHJi+VzhHL57lAydndNZkS4ry1zuqDAgmG VwFeq3iCE66eYNXByJZimixk= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id e3873fdc4d9fcc1f; Sun, 13 Sep 2026 02:15:07 +0000 X-Mizu-Trace-ID: e3873fdc4d9fcc1f X-Migadu-Flow: FLOW_OUT From: Shakeel Butt To: Greg Kroah-Hartman , Tejun Heo , Christian Brauner Cc: Sebastian Andrzej Siewior , Meta kernel team , linux-fsdevel@vger.kernel.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 1/3] kernfs: activate a new node without dropping kernfs_rwsem Date: Sat, 12 Sep 2026 19:14:51 -0700 Message-ID: <20260913021453.21507-2-shakeel.butt@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260913021453.21507-1-shakeel.butt@linux.dev> References: <20260913021453.21507-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 Content-Type: text/plain; charset="utf-8" kernfs_add_one() links the node in, drops the kernfs_rwsem write lock, then calls kernfs_activate(), which takes it again. Roots that do not set KERNFS_ROOT_CREATE_DEACTIVATED, such as sysfs, therefore pay two write locks for every file, directory and symlink created. A new node has no children, so kernfs_activate() would walk only that node. Call kernfs_activate_one() before dropping the lock instead. Its two WARN_ON_ONCE()s still hold: the node was just linked, and nothing can have changed its active count yet. This also closes the window where a node is linked but not yet activated. lock_stat, creating and destroying five dummy netdevs: before after kernfs_rwsem write acquires 1200 830 Assisted-by: LLM Signed-off-by: Shakeel Butt Acked-by: Tejun Heo --- fs/kernfs/dir.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 07abf59f0264..8953e8a07537 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -30,6 +30,8 @@ static char kernfs_pr_cont_buf[PATH_MAX]; /* protected by= pr_cont_lock */ =20 #define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb) =20 +static void kernfs_activate_one(struct kernfs_node *kn); + static bool __kernfs_active(struct kernfs_node *kn) { return atomic_read(&kn->active) >=3D 0; @@ -861,7 +863,6 @@ int kernfs_add_one(struct kernfs_node *kn) } =20 up_write(&root->kernfs_iattr_rwsem); - up_write(&root->kernfs_rwsem); =20 /* * Activate the new node unless CREATE_DEACTIVATED is requested. @@ -869,9 +870,15 @@ int kernfs_add_one(struct kernfs_node *kn) * activating the node with kernfs_activate(). A node which hasn't * been activated is not visible to userland and its removal won't * trigger deactivation. + * + * @kn has no children yet, so kernfs_activate() would walk only @kn. + * Do it here rather than dropping the write lock and taking it again + * for every new node. */ - if (!(kernfs_root(kn)->flags & KERNFS_ROOT_CREATE_DEACTIVATED)) - kernfs_activate(kn); + if (!(root->flags & KERNFS_ROOT_CREATE_DEACTIVATED)) + kernfs_activate_one(kn); + + up_write(&root->kernfs_rwsem); return 0; =20 out_unlock: --=20 2.53.0-Meta From nobody Fri Sep 25 12:05:33 2026 Received: from mta0.migadu.com (out-186.mta0.migadu.com [91.218.175.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C9BAB305667 for ; Sun, 13 Sep 2026 02:15:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.186 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789265722; cv=none; b=PcY/h8gR8WuvdgT/Y4Rzf62+vdDMB8Hy27DaEmwlEvpaZ4lQCl6aUzwFa290ymAqVtprF0ZUcMV3xDebgcHA6GkKyyzc5I/FJq0KaDLtgi2aEZK8v87CBff4vAN9Z3idsI3GXzuk9ISVNS/tpeZicesnHEd+ekmQJH6BYybdAPQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789265722; c=relaxed/simple; bh=pH/pHT3eyv9ohLS5X8BzRXnXn2sTO031AqbiTb+LHC4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=E448tvSOyStpky4oL0nsWkeZJ6XJqCeVrGNyyPAUNf5/C3+esKi+veXAlODtBAsyDrT/R+OMyKMtUV77aR5mAp0uZkG2ajHOJ+2WYggR14NqtlzBn/alezbg787ddkMkZdShje/V+X4O8XCiA1WRGWN6B3RF2FaixYlhzakDaLc= 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=t0XbwN39; arc=none smtp.client-ip=91.218.175.186 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="t0XbwN39" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=pH/pHT3eyv9ohLS5X8BzRXnXn2sTO031AqbiTb+LHC4=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1789265718; v=1; x=1789870518; b=t0XbwN397Ni5im13fTnmUhS1f3gUleWx7FEKPEJR8wLArAU/dxefilpEKMr6gIpuHuiFibX/ 02Troraj27XF94PFQr7cWub9N7Yrg3N5s1nYJOQwlpzq8iCN/kbYMKFFN5+kqQuXiuzSPr12o7a YuAtOyOYxmMj9b5RN4ItJwbc= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id 63251dd25ef417dc; Sun, 13 Sep 2026 02:15:10 +0000 X-Mizu-Trace-ID: 63251dd25ef417dc X-Migadu-Flow: FLOW_OUT From: Shakeel Butt To: Greg Kroah-Hartman , Tejun Heo , Christian Brauner Cc: Sebastian Andrzej Siewior , Meta kernel team , linux-fsdevel@vger.kernel.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 2/3] kernfs: allocate the new name outside kernfs_rwsem Date: Sat, 12 Sep 2026 19:14:52 -0700 Message-ID: <20260913021453.21507-3-shakeel.butt@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260913021453.21507-1-shakeel.butt@linux.dev> References: <20260913021453.21507-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 Content-Type: text/plain; charset="utf-8" kernfs_rename_ns() calls kstrdup_const() while holding the kernfs_rwsem write lock. It is the only GFP_KERNEL allocation under that lock in kernfs, so a rename can enter reclaim while every create, remove and rename in the hierarchy waits behind it. Copy the name before taking the lock and free the copy again if the rename turns out not to need it. A rename that keeps the name, hits a collision or finds the node gone now does one extra kstrdup_const(); renames are rare. -ENOMEM is still reported at the same point as before, so nothing changes about which error a caller sees. Assisted-by: LLM Signed-off-by: Shakeel Butt Acked-by: Tejun Heo --- fs/kernfs/dir.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 8953e8a07537..3bbdd9a8acc8 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1819,6 +1819,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct k= ernfs_node *new_parent, const char *new_name, const struct ns_common *new_ns) { struct kernfs_node *old_parent; + const char *dup_name =3D NULL; struct kernfs_root *root; const char *old_name; bool reparent; @@ -1828,6 +1829,9 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct k= ernfs_node *new_parent, if (!rcu_access_pointer(kn->__parent)) return -EINVAL; =20 + if (new_name) + dup_name =3D kstrdup_const(new_name, GFP_KERNEL); + root =3D kernfs_root(kn); down_write(&root->kernfs_rwsem); =20 @@ -1859,9 +1863,10 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct = kernfs_node *new_parent, /* rename kernfs_node */ if (strcmp(old_name, new_name) !=3D 0) { error =3D -ENOMEM; - new_name =3D kstrdup_const(new_name, GFP_KERNEL); - if (!new_name) + if (!dup_name) goto out; + new_name =3D dup_name; + dup_name =3D NULL; } else { new_name =3D NULL; } @@ -1901,6 +1906,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct k= ernfs_node *new_parent, error =3D 0; out: up_write(&root->kernfs_rwsem); + kfree_const(dup_name); return error; } =20 --=20 2.53.0-Meta From nobody Fri Sep 25 12:05:33 2026 Received: from mta0.migadu.com (out-189.mta0.migadu.com [91.218.175.189]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D7F271A3166 for ; Sun, 13 Sep 2026 02:15:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789265727; cv=none; b=Jt+0vvI5l55ZaDMKgQ6dZYcitts1PiBOrkZE+3Oacj/ca3TpTE8+YloYiq5VdcwBiuZ6p37vI5kxehv7iLNV7h/QvAGFk4SsTcS1913YiSH9RHfEyEXgWnylS5DMvbQBqFUhHKSEFzjJOpcNLqip0dMLdC4gL5GzmRzpyK4Turo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789265727; c=relaxed/simple; bh=XAH7CnimcRNQoRRE+99q5yKGEMhsVyJ4d/BtZs/Wuxc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=euNoRYgpArZogDmBoIorLcqYZkUbGDhS29KNIYNjF4RBpMEA8YtYCXqPdrrFWkFHt6gJg9tmZMbabKtHrnQp+CrhSx4w76rDstXzBLVQubpZzjgacn/K39Zc19QbrIIhuNwBfcjPpfXROwUpevvUUTnbaILq3T6BSPZU5BPHOkU= 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=X+pzcJYP; arc=none smtp.client-ip=91.218.175.189 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="X+pzcJYP" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=XAH7CnimcRNQoRRE+99q5yKGEMhsVyJ4d/BtZs/Wuxc=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1789265723; v=1; x=1789870523; b=X+pzcJYPPgFr4zZgH8s8O5SHInfbQmbQPSAAPcWVYXxjAD2FhpxBH2rbLX4JOKzq2YF5pjhj ZHfaZP2ecAizAt6IZYwkguXOm0k4riPVDCa+QeUekkxc25+iyWLyuIaS4njzu/su1kOBFuLfgpG i3UBL/idVxdj1ycRePZANleY= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id 71917a76d207099f; Sun, 13 Sep 2026 02:15:23 +0000 X-Mizu-Trace-ID: 71917a76d207099f X-Migadu-Flow: FLOW_OUT From: Shakeel Butt To: Greg Kroah-Hartman , Tejun Heo , Christian Brauner Cc: Sebastian Andrzej Siewior , Meta kernel team , linux-fsdevel@vger.kernel.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 3/3] kernfs: free the old name outside kernfs_rwsem Date: Sat, 12 Sep 2026 19:14:53 -0700 Message-ID: <20260913021453.21507-4-shakeel.butt@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260913021453.21507-1-shakeel.butt@linux.dev> References: <20260913021453.21507-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 Content-Type: text/plain; charset="utf-8" kernfs_rename_ns() frees the replaced name with kfree_rcu_mightsleep() while still holding the kernfs_rwsem write lock. If the batching allocation fails, which is what happens under memory pressure, kvfree_call_rcu() falls back to a full synchronize_rcu() before freeing. A rename can then wait out a grace period with the write lock held, and every create, remove and rename in the hierarchy waits with it. The name is already unpublished by then, so nothing needs the free to happen under the lock. Move it past the unlock. Assisted-by: LLM Signed-off-by: Shakeel Butt Acked-by: Tejun Heo --- fs/kernfs/dir.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 1fa288a48d7c..b071071e51b0 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1820,6 +1820,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct k= ernfs_node *new_parent, { struct kernfs_node *old_parent; const char *dup_name =3D NULL; + const char *put_name =3D NULL; struct kernfs_root *root; const char *old_name; bool reparent; @@ -1905,12 +1906,14 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct= kernfs_node *new_parent, kernfs_link_sibling(kn); =20 if (new_name && !is_kernel_rodata((unsigned long)old_name)) - kfree_rcu_mightsleep(old_name); + put_name =3D old_name; =20 error =3D 0; out: up_write(&root->kernfs_rwsem); kfree_const(dup_name); + if (put_name) + kfree_rcu_mightsleep(put_name); return error; } =20 --=20 2.53.0-Meta