Netdev List
 help / color / mirror / Atom feed
From: Kuniyuki Iwashima <kuniyu@google.com>
To: David Ahern <dsahern@kernel.org>,
	Ido Schimmel <idosch@nvidia.com>,
	 "David S . Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@kernel.org>,
	 Jakub Kicinski <kuba@kernel.org>,
	Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>,
	Chris J Arges <carges@cloudflare.com>,
	 Kuniyuki Iwashima <kuniyu@google.com>,
	Kuniyuki Iwashima <kuni1840@gmail.com>,
	netdev@vger.kernel.org
Subject: [PATCH v1 net-next 3/5] net: Track state in ops_undo_list().
Date: Sun, 27 Sep 2026 20:23:40 +0000	[thread overview]
Message-ID: <20260927202429.2452589-4-kuniyu@google.com> (raw)
In-Reply-To: <20260927202429.2452589-1-kuniyu@google.com>

We will call rt_flush_dev() and rt6_uncached_list_flush_dev()
from ->pre_exit_batch().

Then, we want them to return early when called again from
 ->exit_rtnl() or default_device_exit_batch().

However, we cannot simply return early when !check_net(net).

In the following cases, even if check_net(net) is false,
we cannot skip rt_flush_dev() / rt6_uncached_list_flush_dev():

  1. some ->pre_exit() call unregister_netdevice() before
     fib_net_ops (e.g. ovs_pre_exit_net(), l2tp_pre_exit_net()).

  2. ->dellink() could call unregister_netdevice() for another
     netdev in a dying netns queued for the next cleanup_net()
     batch, for which ->pre_exit_batch() has not been called
     yet (e.g. veth).

Thus, we need a clear flag to indicate that ->pre_exit_batch()
has already been called.

Let's add net->undo_state and update it only for dying netns.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
 include/net/net_namespace.h | 9 +++++++++
 net/core/net_namespace.c    | 7 +++++++
 2 files changed, 16 insertions(+)

diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 58b2601bb869..6a817326fbb8 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -57,6 +57,9 @@ struct uevent_sock;
 struct netns_ipvs;
 struct bpf_prog;
 
+enum {
+	NET_PRE_EXIT_DONE = 1,
+};
 
 #define NETDEV_HASHBITS    8
 #define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS)
@@ -125,6 +128,7 @@ struct net {
 	 * it is critical that it is on a read_mostly cache line.
 	 */
 	u32			hash_mix;
+	u8			undo_state;
 
 	struct net_device       *loopback_dev;          /* The loopback */
 
@@ -364,6 +368,11 @@ static inline bool net_initialized(const struct net *net)
 	return READ_ONCE(net->list.next);
 }
 
+static inline bool net_pre_exit_done(const struct net *net)
+{
+	return READ_ONCE(net->undo_state) >= NET_PRE_EXIT_DONE;
+}
+
 static inline void __netns_tracker_alloc(struct net *net,
 					 netns_tracker *tracker,
 					 bool refcounted,
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 476fbf913bad..9e2462bfa478 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -226,7 +226,9 @@ static void ops_undo_list(const struct list_head *ops_list,
 			  bool expedite_rcu)
 {
 	const struct pernet_operations *saved_ops;
+	bool dying = ops_list == &pernet_list;
 	bool hold_rtnl = false;
+	struct net *net;
 
 	if (!ops)
 		ops = list_entry(ops_list, typeof(*ops), list);
@@ -248,6 +250,11 @@ static void ops_undo_list(const struct list_head *ops_list,
 	else
 		synchronize_rcu();
 
+	if (dying) {
+		list_for_each_entry(net, net_exit_list, exit_list)
+			WRITE_ONCE(net->undo_state, NET_PRE_EXIT_DONE);
+	}
+
 	if (hold_rtnl)
 		ops_exit_rtnl_list(ops_list, saved_ops, net_exit_list);
 
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


  parent reply	other threads:[~2026-09-27 20:24 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-27 20:23 [PATCH v1 net-next 0/5] ip: Batch flushing uncached routes for dying netns Kuniyuki Iwashima
2026-09-27 20:23 ` [PATCH v1 net-next 1/5] net: Remove net->is_dying Kuniyuki Iwashima
2026-09-29  6:26   ` netdev-bot+sashiko
2026-09-27 20:23 ` [PATCH v1 net-next 2/5] net: Add ->pre_exit_batch() to struct pernet_operations Kuniyuki Iwashima
2026-09-29  6:26   ` netdev-bot+sashiko
2026-09-27 20:23 ` Kuniyuki Iwashima [this message]
2026-09-27 20:23 ` [PATCH v1 net-next 4/5] ipv4: Batch rt_flush_dev() for dying netns Kuniyuki Iwashima
2026-09-27 22:51   ` Eric Dumazet
2026-09-28 16:33     ` Kuniyuki Iwashima
2026-09-29  6:26   ` netdev-bot+sashiko
2026-09-27 20:23 ` [PATCH v1 net-next 5/5] ipv6: Batch rt6_uncached_list_flush_dev() " Kuniyuki Iwashima
2026-09-29  6:26   ` netdev-bot+sashiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260927202429.2452589-4-kuniyu@google.com \
    --to=kuniyu@google.com \
    --cc=carges@cloudflare.com \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=idosch@nvidia.com \
    --cc=kuba@kernel.org \
    --cc=kuni1840@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox