Thread (26 messages) 26 messages, 3 authors, 8d ago

Re: [PATCH v2 net-next 06/14] net: Add per-netns netdev unregistration infra.

From: Kuniyuki Iwashima <kuniyu@google.com>
Date: 2026-07-06 16:35:04

Replying to Sashiko review,

On Thu, Jul 2, 2026 at 5:10 PM Kuniyuki Iwashima [off-list ref] wrote:
[...]
Note that unregister_netdevice_move_net() does not need to call
rtnl_net_queue_work() because __dev_change_net_namespace() is
(supposed to be) called with rtnl_net_lock().  (Not all callers
hold it yet, but the race does not happen until all callers
are converted and RTNL is removed.)
[...]
+static void unregister_netdevice_move_net(struct net *net_old,
+                                         struct net *net,
+                                         struct net_device *dev)
+{
+       if (net_old > net) {
+               spin_lock(&net->dev_unreg_lock);
+               spin_lock_nested(&net_old->dev_unreg_lock, SINGLE_DEPTH_NESTING);
+       } else {
+               spin_lock(&net_old->dev_unreg_lock);
+               spin_lock_nested(&net->dev_unreg_lock, SINGLE_DEPTH_NESTING);
+       }
+
+       if (!list_empty(&dev->unreg_list_net)) {
+               list_del(&dev->unreg_list_net);
+               list_add_tail(&dev->unreg_list_net, &net->dev_unreg_head);
+       }
+
+       spin_unlock(&net_old->dev_unreg_lock);
+       spin_unlock(&net->dev_unreg_lock);
+}
+
+void unregister_netdevice_many_net(struct net *net)
+{
+       struct net_device *dev, *tmp;
+       LIST_HEAD(unreg_head_net);
+       LIST_HEAD(unreg_head);
+
+       spin_lock(&net->dev_unreg_lock);
+       list_splice_init(&net->dev_unreg_head, &unreg_head_net);
+       spin_unlock(&net->dev_unreg_lock);
+
+       list_for_each_entry_safe(dev, tmp, &unreg_head_net, unreg_list_net) {
+               list_del_init(&dev->unreg_list_net);
+               list_add_tail(&dev->unreg_list, &unreg_head);
+       }
---8<---
Will this result in a stalled unregistration if a cross-netns device is deleted
and concurrently moved to a new namespace?

If a user triggers deletion, unregister_netdevice_queue_net() queues the device
in dev_unreg_head and schedules the async workqueue. Because unregistration
runs asynchronously, dev->reg_state remains NETREG_REGISTERED initially.
If the pending device is concurrently moved to a new netns via

dev_change_net_namespace(), unregister_netdevice_move_net() correctly transfers
the device to the new netns's dev_unreg_head list.

However, does this block miss a call to rtnl_net_queue_work(net) to schedule
processing for the new netns?
---8<---

I didn't add rtnl_net_queue_work() intentionally as mentioned in the commit
message.

For now, such a race does not occur thanks to RTNL.

Once RTNL is removed, all dev_change_net_namespace() callers must be
called under per-netns RTNL, so even if the race occurred, the dev would be
removed at __rtnl_net_unlock().
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help