Commit 779596b8 authored by Eric Dumazet's avatar Eric Dumazet Committed by Zheng Zengkai
Browse files

net: avoid quadratic behavior in netdev_wait_allrefs_any()

net-next inclusion
from net-next-v5.17-rc5
commit 86213f80
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4VZN0?from=project-issue

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=86213f80da1b1d007721cc22e04b5f5d0da33127



--------------------------------

If the list of devices has N elements, netdev_wait_allrefs_any()
is called N times, and linkwatch_forget_dev() is called N*(N-1)/2 times.

Fix this by calling linkwatch_forget_dev() only once per device.

Fixes: faab39f6 ("net: allow out-of-order netdev unregistration")
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20220218065430.2613262-1-eric.dumazet@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarZiyang Xuan <william.xuanziyang@huawei.com>
Reviewed-by: default avatarWei Yongjun <weiyongjun1@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 0de74d1c
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -10261,9 +10261,6 @@ static struct net_device *netdev_wait_allrefs_any(struct list_head *list)
	struct net_device *dev;
	int wait = 0;

	list_for_each_entry(dev, list, todo_list)
		linkwatch_forget_dev(dev);

	rebroadcast_time = warning_time = jiffies;

	list_for_each_entry(dev, list, todo_list)
@@ -10380,6 +10377,7 @@ void netdev_run_todo(void)
		}

		dev->reg_state = NETREG_UNREGISTERED;
		linkwatch_forget_dev(dev);
	}

	while (!list_empty(&list)) {