From: Kuniyuki Iwashima <kuniyu@google.com>
To: Andrew Lunn <andrew+netdev@lunn.ch>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>,
Kuniyuki Iwashima <kuniyu@google.com>,
Kuniyuki Iwashima <kuni1840@gmail.com>,
netdev@vger.kernel.org
Subject: [PATCH v1 net-next 3/3] geneve: Support per-netns netdev unregistration.
Date: Fri, 31 Jul 2026 16:45:55 +0000 [thread overview]
Message-ID: <20260731164612.2148830-4-kuniyu@google.com> (raw)
In-Reply-To: <20260731164612.2148830-1-kuniyu@google.com>
geneve_exit_rtnl_net() iterates geneve devices whose sockets
are in the dying netns and queues them for destruction.
So the devices may reside in different netns.
Let's use unregister_netdevice_queue_net() to support per-netns
device unregistration.
list_del() is changed to list_del_init() to avoid queueing the
same device twice.
Even after geneve_exit_rtnl_net() queues a cross-netns geneve
device, geneve_dellink() can be called concurrently for it.
In such a case, __rtnl_net_unlock() will perform the unregistration.
Note that geneve uses register_pernet_subsys() instead of _device(),
so default_device_exit_batch() guarantees that the async per-netns
works are flushed before ->exit().
Tested:
1. Create geneve device across two netns.
# ip netns add ns1
# ip netns add ns2
# ip -n ns1 link add geneve0 link-netns ns2 type geneve external
2. Run bpftrace to check that geneve_uninit() is called between
->exit_rtnl() and ->exit().
# bpftrace -e '#include <linux/netdevice.h>
kprobe:geneve_uninit {
$dev = (struct net_device *)arg0;
printf("PID: %d | DEV: %s%s\n", pid, $dev->name, kstack());
}
kprobe:geneve_exit_rtnl_net,
kprobe:geneve_exit_net {
printf("PID: %d%s\n", pid, kstack());
}'
3. Remove the netns where the geneve socket resides
# ip netns del ns2
Now, we can see geneve0 is unregistered by per-netns work
instead of cleanup_net() and it finishes before ->exit() to
avoid WARN_ON_ONCE(!list_empty(&gn->sock_list)) there.
PID: 571
geneve_exit_rtnl_net+5
ops_undo_list+702
cleanup_net+1122
process_scheduled_works+2538
...
PID: 1047 | DEV: geneve0
geneve_uninit+5
unregister_netdevice_many_notify+7129
unregister_netdevice_many_net+1050
rtnl_net_work_func+136
process_scheduled_works+2538
...
PID: 571
geneve_exit_net+5
ops_undo_list+1064
cleanup_net+1122
process_scheduled_works+2538
...
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
drivers/net/geneve.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index f456a85dca77..a6a8978e3b81 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -2502,12 +2502,13 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
return err;
}
-static void __geneve_dellink(struct net_device *dev, struct list_head *head)
+static void __geneve_dellink(struct net *net, struct net_device *dev,
+ struct list_head *head)
{
struct geneve_dev *geneve = netdev_priv(dev);
- list_del(&geneve->next);
- unregister_netdevice_queue(dev, head);
+ list_del_init(&geneve->next);
+ unregister_netdevice_queue_net(net, dev, head);
}
static void geneve_dellink(struct net_device *dev, struct list_head *head)
@@ -2518,7 +2519,8 @@ static void geneve_dellink(struct net_device *dev, struct list_head *head)
gn = net_generic(geneve->net, geneve_net_id);
mutex_lock(&gn->lock);
- __geneve_dellink(dev, head);
+ if (!list_empty(&geneve->next))
+ __geneve_dellink(dev_net(dev), dev, head);
mutex_unlock(&gn->lock);
}
@@ -2754,7 +2756,7 @@ static void __net_exit geneve_exit_rtnl_net(struct net *net,
mutex_lock(&gn->lock);
list_for_each_entry_safe(geneve, next, &gn->geneve_list, next)
- __geneve_dellink(geneve->dev, dev_to_kill);
+ __geneve_dellink(net, geneve->dev, dev_to_kill);
mutex_unlock(&gn->lock);
}
--
2.55.0.571.g244d577d93-goog
next prev parent reply other threads:[~2026-07-31 16:46 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 16:45 [PATCH v1 net-next 0/3] geneve: Support per-netns device unregistration Kuniyuki Iwashima
2026-07-31 16:45 ` [PATCH v1 net-next 1/3] geneve: Unlink geneve->sock[46].hlist[46].hlist in __geneve_sock_release() Kuniyuki Iwashima
2026-07-31 16:45 ` [PATCH v1 net-next 2/3] geneve: Protect geneve_net and geneve_sock with per-netns mutex Kuniyuki Iwashima
2026-07-31 16:45 ` Kuniyuki Iwashima [this message]
2026-08-04 13:47 ` [PATCH v1 net-next 3/3] geneve: Support per-netns netdev unregistration Paolo Abeni
2026-08-04 15:24 ` Kuniyuki Iwashima
2026-08-04 15:35 ` Ilya Maximets
2026-08-04 17:38 ` Kuniyuki Iwashima
2026-08-04 17:34 ` Paolo Abeni
2026-08-04 17:37 ` Kuniyuki Iwashima
2026-08-04 14:00 ` [PATCH v1 net-next 0/3] geneve: Support per-netns device unregistration patchwork-bot+netdevbpf
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=20260731164612.2148830-4-kuniyu@google.com \
--to=kuniyu@google.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.