From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 846FD30C153; Sun, 7 Jun 2026 10:06:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780826807; cv=none; b=GUzL6YoTEAnhJqtTYr+8fsXc9k1jfzkv4YGhQlokb2kiY+ulpZAgI0/2RPxuH+KLAqwmYKPdNIw0PQrO/Uj5CA4eOSxv2k6d4mzJ6Obj/sEBOJ+PF6rxm5turMWV8y7jJTz32jf7SEIjHNEogO6uaNkPYg2cwJ5kLy91IxI7++s= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780826807; c=relaxed/simple; bh=gUy+pMe4S221N0uuRtqzNOE8DAvnwGwnmyu7XCOQmfI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hMxVK6biWecz57WPWRA8LEY3qdSJzN8KeQWFw0UeCGXoE2+lG10JagP3OQI4w/JPMLPVNfKPIlKen3DmP9qVFCNVIQm0nQ3YkOjGo5pY/J/dMSqgAZDIfsLLa6tNva1urlxc1VDSrCdVu5MveJaAopufxxNKEB8bwcezSA7mLRo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=iisAsiDW; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="iisAsiDW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C7C9D1F00898; Sun, 7 Jun 2026 10:06:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1780826806; bh=jB/8ppo0QQVGHJ+EYIQm7gHDqjKgQwMo6JD1hyvDDow=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=iisAsiDWEHbFK4E9NTfgoabS+wHb7UZ/jG4e9fa6Kq7Hc1602a6Hj5XFoakFPgmjm hIoW8wPXI72YIE2m47yuF0OtvE+ee7kkGGuzL294bmLtI+Aww3DMoRjY4gtIHc8l6v HxOjNgOGMuZ2qSd3s7P5FG7kdBhVSXHZ18FTqFfQ= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Usama Arif , Steffen Klassert , Sasha Levin Subject: [PATCH 7.0 004/332] xfrm: move policy_bydst RCU sync from per-netns .exit to .pre_exit Date: Sun, 7 Jun 2026 11:56:13 +0200 Message-ID: <20260607095728.192985321@linuxfoundation.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260607095728.031258202@linuxfoundation.org> References: <20260607095728.031258202@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 7.0-stable review patch. If anyone has any objections, please let me know. ------------------ From: Usama Arif [ Upstream commit 3e52417318473782012b236d0325bf7d2266a597 ] The struct pernet_operations docstring in include/net/net_namespace.h explicitly warns against blocking RCU primitives in .exit handlers: Exit methods using blocking RCU primitives, such as synchronize_rcu(), should be implemented via exit_batch. [...] Please, avoid synchronize_rcu() at all, where it's possible. Note that a combination of pre_exit() and exit() can be used, since a synchronize_rcu() is guaranteed between the calls. xfrm_policy_fini() violates this: it calls synchronize_rcu() before freeing the policy_bydst hash tables (so no RCU reader is mid- traversal at free time), but runs from xfrm_net_ops.exit -- once per namespace -- so a cleanup_net() of N namespaces pays N full RCU grace periods serially. Use the documented pre_exit/exit split. Move the policy flush (and the workqueue drains it depends on) into a new .pre_exit handler; xfrm_policy_fini() then runs in .exit and frees the hash tables after the synchronize_rcu_expedited() that cleanup_net() guarantees between the two phases. Providing O(1) RCU grace periods per batch instead of O(N). Observed on Linux 6.18 with a workload doing unshare(CLONE_NEWNET) at ~13/sec sustained: cleanup_net() and the netns_wq rescuer kthread both stuck in xfrm_policy_fini()'s synchronize_rcu(), >300k struct net accumulated in the cleanup queue, Percpu in /proc/meminfo climbed to 130+ GB on 256-CPU hosts, and memcg OOMs followed. setup_net and __put_net counts were balanced, ruling out a refcount leak. Fixes: 069daad4f2ae ("xfrm: Wait for RCU readers during policy netns exit") Signed-off-by: Usama Arif Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin --- net/xfrm/xfrm_policy.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index a872af5610dc95..71bdb781cb0292 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -4276,21 +4276,21 @@ static int __net_init xfrm_policy_init(struct net *net) return -ENOMEM; } -static void xfrm_policy_fini(struct net *net) +static void __net_exit xfrm_net_pre_exit(struct net *net) { - struct xfrm_pol_inexact_bin *b, *t; - unsigned int sz; - int dir; - disable_work_sync(&net->xfrm.policy_hthresh.work); - flush_work(&net->xfrm.policy_hash_work); #ifdef CONFIG_XFRM_SUB_POLICY xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, false); #endif xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, false); +} - synchronize_rcu(); +static void xfrm_policy_fini(struct net *net) +{ + struct xfrm_pol_inexact_bin *b, *t; + unsigned int sz; + int dir; WARN_ON(!list_empty(&net->xfrm.policy_all)); @@ -4368,6 +4368,7 @@ static void __net_exit xfrm_net_exit(struct net *net) static struct pernet_operations __net_initdata xfrm_net_ops = { .init = xfrm_net_init, + .pre_exit = xfrm_net_pre_exit, .exit = xfrm_net_exit, }; -- 2.53.0