summaryrefslogtreecommitdiff
path: root/net/core/link_watch.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2023-12-05 19:00:11 +0300
committerJakub Kicinski <kuba@kernel.org>2023-12-07 06:25:43 +0300
commitb8dbbbc535a95acd66035cf75872cd7524c0b12f (patch)
treee743e5a1afc2cbaff05c51992902b1c8ef84463f /net/core/link_watch.c
parent5a08d0065a915ccf325563d7ca57fa8b4897881c (diff)
downloadlinux-b8dbbbc535a95acd66035cf75872cd7524c0b12f.tar.xz
net: rtnetlink: remove local list in __linkwatch_run_queue()
Due to linkwatch_forget_dev() (and perhaps others?) checking for list_empty(&dev->link_watch_list), we must have all manipulations of even the local on-stack list 'wrk' here under spinlock, since even that list can be reached otherwise via dev->link_watch_list. This is already the case, but makes this a bit counter-intuitive, often local lists are used to _not_ have to use locking for their local use. Remove the local list as it doesn't seem to serve any purpose. While at it, move a variable declaration into the loop using it. Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Link: https://lore.kernel.org/r/20231205170011.56576dcc1727.I698b72219d9f6ce789bd209b8f6dffd0ca32a8f2@changeid Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/core/link_watch.c')
-rw-r--r--net/core/link_watch.c13
1 files changed, 4 insertions, 9 deletions
diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index a19f21403339..7be5b3ab32bd 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -192,8 +192,6 @@ static void __linkwatch_run_queue(int urgent_only)
#define MAX_DO_DEV_PER_LOOP 100
int do_dev = MAX_DO_DEV_PER_LOOP;
- struct net_device *dev;
- LIST_HEAD(wrk);
/* Give urgent case more budget */
if (urgent_only)
@@ -215,11 +213,11 @@ static void __linkwatch_run_queue(int urgent_only)
clear_bit(LW_URGENT, &linkwatch_flags);
spin_lock_irq(&lweventlist_lock);
- list_splice_init(&lweventlist, &wrk);
+ while (!list_empty(&lweventlist) && do_dev > 0) {
+ struct net_device *dev;
- while (!list_empty(&wrk) && do_dev > 0) {
-
- dev = list_first_entry(&wrk, struct net_device, link_watch_list);
+ dev = list_first_entry(&lweventlist, struct net_device,
+ link_watch_list);
list_del_init(&dev->link_watch_list);
if (!netif_device_present(dev) ||
@@ -237,9 +235,6 @@ static void __linkwatch_run_queue(int urgent_only)
spin_lock_irq(&lweventlist_lock);
}
- /* Add the remaining work back to lweventlist */
- list_splice_init(&wrk, &lweventlist);
-
if (!list_empty(&lweventlist))
linkwatch_schedule_work(0);
spin_unlock_irq(&lweventlist_lock);