diff --git a/net/core/link_watch.c b/net/core/link_watch.c index 7be5b3ab32bd..429571c258da 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c @@ -192,6 +192,11 @@ static void __linkwatch_run_queue(int urgent_only) #define MAX_DO_DEV_PER_LOOP 100 int do_dev = MAX_DO_DEV_PER_LOOP; + /* Use a local list here since we add non-urgent + * events back to the global one when called with + * urgent_only=1. + */ + LIST_HEAD(wrk); /* Give urgent case more budget */ if (urgent_only) @@ -213,11 +218,12 @@ static void __linkwatch_run_queue(int urgent_only) clear_bit(LW_URGENT, &linkwatch_flags); spin_lock_irq(&lweventlist_lock); - while (!list_empty(&lweventlist) && do_dev > 0) { + list_splice_init(&lweventlist, &wrk); + + while (!list_empty(&wrk) && do_dev > 0) { struct net_device *dev; - dev = list_first_entry(&lweventlist, struct net_device, - link_watch_list); + dev = list_first_entry(&wrk, struct net_device, link_watch_list); list_del_init(&dev->link_watch_list); if (!netif_device_present(dev) || @@ -235,6 +241,9 @@ 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);