hc
2024-02-20 e636c8d336489bf3eed5878299e6cc045bbad077
....@@ -1,14 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Linux network device link state notification
34 *
45 * Author:
56 * Stefan Rompf <sux@loplof.de>
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * as published by the Free Software Foundation; either version
10
- * 2 of the License, or (at your option) any later version.
11
- *
127 */
138
149 #include <linux/module.h>
....@@ -39,6 +34,9 @@
3934
4035 static unsigned char default_operstate(const struct net_device *dev)
4136 {
37
+ if (netif_testing(dev))
38
+ return IF_OPER_TESTING;
39
+
4240 if (!netif_carrier_ok(dev))
4341 return (dev->ifindex != dev_get_iflink(dev) ?
4442 IF_OPER_LOWERLAYERDOWN : IF_OPER_DOWN);
....@@ -60,11 +58,15 @@
6058 write_lock_bh(&dev_base_lock);
6159
6260 switch(dev->link_mode) {
61
+ case IF_LINK_MODE_TESTING:
62
+ if (operstate == IF_OPER_UP)
63
+ operstate = IF_OPER_TESTING;
64
+ break;
65
+
6366 case IF_LINK_MODE_DORMANT:
6467 if (operstate == IF_OPER_UP)
6568 operstate = IF_OPER_DORMANT;
6669 break;
67
-
6870 case IF_LINK_MODE_DEFAULT:
6971 default:
7072 break;
....@@ -79,7 +81,8 @@
7981 void linkwatch_init_dev(struct net_device *dev)
8082 {
8183 /* Handle pre-registration link state changes */
82
- if (!netif_carrier_ok(dev) || netif_dormant(dev))
84
+ if (!netif_carrier_ok(dev) || netif_dormant(dev) ||
85
+ netif_testing(dev))
8386 rfc2863_policy(dev);
8487 }
8588
....@@ -168,8 +171,15 @@
168171
169172 static void __linkwatch_run_queue(int urgent_only)
170173 {
174
+#define MAX_DO_DEV_PER_LOOP 100
175
+
176
+ int do_dev = MAX_DO_DEV_PER_LOOP;
171177 struct net_device *dev;
172178 LIST_HEAD(wrk);
179
+
180
+ /* Give urgent case more budget */
181
+ if (urgent_only)
182
+ do_dev += MAX_DO_DEV_PER_LOOP;
173183
174184 /*
175185 * Limit the number of linkwatch events to one
....@@ -189,20 +199,25 @@
189199 spin_lock_irq(&lweventlist_lock);
190200 list_splice_init(&lweventlist, &wrk);
191201
192
- while (!list_empty(&wrk)) {
202
+ while (!list_empty(&wrk) && do_dev > 0) {
193203
194204 dev = list_first_entry(&wrk, struct net_device, link_watch_list);
195205 list_del_init(&dev->link_watch_list);
196206
197
- if (urgent_only && !linkwatch_urgent_event(dev)) {
207
+ if (!netif_device_present(dev) ||
208
+ (urgent_only && !linkwatch_urgent_event(dev))) {
198209 list_add_tail(&dev->link_watch_list, &lweventlist);
199210 continue;
200211 }
201212 spin_unlock_irq(&lweventlist_lock);
202213 linkwatch_do_dev(dev);
214
+ do_dev--;
203215 spin_lock_irq(&lweventlist_lock);
204216 }
205217
218
+ /* Add the remaining work back to lweventlist */
219
+ list_splice_init(&wrk, &lweventlist);
220
+
206221 if (!list_empty(&lweventlist))
207222 linkwatch_schedule_work(0);
208223 spin_unlock_irq(&lweventlist_lock);