Skip to content

Commit e759e1e

Browse files
edumazetkuba-moo
authored andcommitted
net: revert RTNL changes in unregister_netdevice_many_notify()
This patch reverts following changes: 83419b6 net: reduce RTNL hold duration in unregister_netdevice_many_notify() (part 2) ae646f1 net: reduce RTNL hold duration in unregister_netdevice_many_notify() (part 1) cfa579f net: no longer hold RTNL while calling flush_all_backlogs() This caused issues in layers holding a private mutex: cleanup_net() rtnl_lock(); mutex_lock(subsystem_mutex); unregister_netdevice(); rtnl_unlock(); // LOCKDEP violation rtnl_lock(); I will revisit this in next cycle, opt-in for the new behavior from safe contexts only. Fixes: cfa579f ("net: no longer hold RTNL while calling flush_all_backlogs()") Fixes: ae646f1 ("net: reduce RTNL hold duration in unregister_netdevice_many_notify() (part 1)") Fixes: 83419b6 ("net: reduce RTNL hold duration in unregister_netdevice_many_notify() (part 2)") Reported-by: [email protected] Closes: https://lore.kernel.org/netdev/[email protected]/ Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: Kuniyuki Iwashima <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 0f5697f commit e759e1e

File tree

1 file changed

+3
-30
lines changed

1 file changed

+3
-30
lines changed

net/core/dev.c

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10264,37 +10264,14 @@ static bool from_cleanup_net(void)
1026410264
#endif
1026510265
}
1026610266

10267-
static void rtnl_drop_if_cleanup_net(void)
10268-
{
10269-
if (from_cleanup_net())
10270-
__rtnl_unlock();
10271-
}
10272-
10273-
static void rtnl_acquire_if_cleanup_net(void)
10274-
{
10275-
if (from_cleanup_net())
10276-
rtnl_lock();
10277-
}
10278-
1027910267
/* Delayed registration/unregisteration */
1028010268
LIST_HEAD(net_todo_list);
10281-
static LIST_HEAD(net_todo_list_for_cleanup_net);
10282-
10283-
/* TODO: net_todo_list/net_todo_list_for_cleanup_net should probably
10284-
* be provided by callers, instead of being static, rtnl protected.
10285-
*/
10286-
static struct list_head *todo_list(void)
10287-
{
10288-
return from_cleanup_net() ? &net_todo_list_for_cleanup_net :
10289-
&net_todo_list;
10290-
}
10291-
1029210269
DECLARE_WAIT_QUEUE_HEAD(netdev_unregistering_wq);
1029310270
atomic_t dev_unreg_count = ATOMIC_INIT(0);
1029410271

1029510272
static void net_set_todo(struct net_device *dev)
1029610273
{
10297-
list_add_tail(&dev->todo_list, todo_list());
10274+
list_add_tail(&dev->todo_list, &net_todo_list);
1029810275
}
1029910276

1030010277
static netdev_features_t netdev_sync_upper_features(struct net_device *lower,
@@ -11144,7 +11121,7 @@ void netdev_run_todo(void)
1114411121
#endif
1114511122

1114611123
/* Snapshot list, allow later requests */
11147-
list_replace_init(todo_list(), &list);
11124+
list_replace_init(&net_todo_list, &list);
1114811125

1114911126
__rtnl_unlock();
1115011127

@@ -11789,11 +11766,9 @@ void unregister_netdevice_many_notify(struct list_head *head,
1178911766
WRITE_ONCE(dev->reg_state, NETREG_UNREGISTERING);
1179011767
netdev_unlock(dev);
1179111768
}
11792-
11793-
rtnl_drop_if_cleanup_net();
1179411769
flush_all_backlogs();
11770+
1179511771
synchronize_net();
11796-
rtnl_acquire_if_cleanup_net();
1179711772

1179811773
list_for_each_entry(dev, head, unreg_list) {
1179911774
struct sk_buff *skb = NULL;
@@ -11853,9 +11828,7 @@ void unregister_netdevice_many_notify(struct list_head *head,
1185311828
#endif
1185411829
}
1185511830

11856-
rtnl_drop_if_cleanup_net();
1185711831
synchronize_net();
11858-
rtnl_acquire_if_cleanup_net();
1185911832

1186011833
list_for_each_entry(dev, head, unreg_list) {
1186111834
netdev_put(dev, &dev->dev_registered_tracker);

0 commit comments

Comments
 (0)