Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.17-rc2 279 lines 6.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Linux network device link state notification 4 * 5 * Author: 6 * Stefan Rompf <sux@loplof.de> 7 */ 8 9#include <linux/module.h> 10#include <linux/netdevice.h> 11#include <linux/if.h> 12#include <net/sock.h> 13#include <net/pkt_sched.h> 14#include <linux/rtnetlink.h> 15#include <linux/jiffies.h> 16#include <linux/spinlock.h> 17#include <linux/workqueue.h> 18#include <linux/bitops.h> 19#include <linux/types.h> 20 21 22enum lw_bits { 23 LW_URGENT = 0, 24}; 25 26static unsigned long linkwatch_flags; 27static unsigned long linkwatch_nextevent; 28 29static void linkwatch_event(struct work_struct *dummy); 30static DECLARE_DELAYED_WORK(linkwatch_work, linkwatch_event); 31 32static LIST_HEAD(lweventlist); 33static DEFINE_SPINLOCK(lweventlist_lock); 34 35static unsigned char default_operstate(const struct net_device *dev) 36{ 37 if (netif_testing(dev)) 38 return IF_OPER_TESTING; 39 40 if (!netif_carrier_ok(dev)) 41 return (dev->ifindex != dev_get_iflink(dev) ? 42 IF_OPER_LOWERLAYERDOWN : IF_OPER_DOWN); 43 44 if (netif_dormant(dev)) 45 return IF_OPER_DORMANT; 46 47 return IF_OPER_UP; 48} 49 50 51static void rfc2863_policy(struct net_device *dev) 52{ 53 unsigned char operstate = default_operstate(dev); 54 55 if (operstate == dev->operstate) 56 return; 57 58 write_lock(&dev_base_lock); 59 60 switch(dev->link_mode) { 61 case IF_LINK_MODE_TESTING: 62 if (operstate == IF_OPER_UP) 63 operstate = IF_OPER_TESTING; 64 break; 65 66 case IF_LINK_MODE_DORMANT: 67 if (operstate == IF_OPER_UP) 68 operstate = IF_OPER_DORMANT; 69 break; 70 case IF_LINK_MODE_DEFAULT: 71 default: 72 break; 73 } 74 75 dev->operstate = operstate; 76 77 write_unlock(&dev_base_lock); 78} 79 80 81void linkwatch_init_dev(struct net_device *dev) 82{ 83 /* Handle pre-registration link state changes */ 84 if (!netif_carrier_ok(dev) || netif_dormant(dev) || 85 netif_testing(dev)) 86 rfc2863_policy(dev); 87} 88 89 90static bool linkwatch_urgent_event(struct net_device *dev) 91{ 92 if (!netif_running(dev)) 93 return false; 94 95 if (dev->ifindex != dev_get_iflink(dev)) 96 return true; 97 98 if (netif_is_lag_port(dev) || netif_is_lag_master(dev)) 99 return true; 100 101 return netif_carrier_ok(dev) && qdisc_tx_changing(dev); 102} 103 104 105static void linkwatch_add_event(struct net_device *dev) 106{ 107 unsigned long flags; 108 109 spin_lock_irqsave(&lweventlist_lock, flags); 110 if (list_empty(&dev->link_watch_list)) { 111 list_add_tail(&dev->link_watch_list, &lweventlist); 112 dev_hold_track(dev, &dev->linkwatch_dev_tracker, GFP_ATOMIC); 113 } 114 spin_unlock_irqrestore(&lweventlist_lock, flags); 115} 116 117 118static void linkwatch_schedule_work(int urgent) 119{ 120 unsigned long delay = linkwatch_nextevent - jiffies; 121 122 if (test_bit(LW_URGENT, &linkwatch_flags)) 123 return; 124 125 /* Minimise down-time: drop delay for up event. */ 126 if (urgent) { 127 if (test_and_set_bit(LW_URGENT, &linkwatch_flags)) 128 return; 129 delay = 0; 130 } 131 132 /* If we wrap around we'll delay it by at most HZ. */ 133 if (delay > HZ) 134 delay = 0; 135 136 /* 137 * If urgent, schedule immediate execution; otherwise, don't 138 * override the existing timer. 139 */ 140 if (test_bit(LW_URGENT, &linkwatch_flags)) 141 mod_delayed_work(system_wq, &linkwatch_work, 0); 142 else 143 schedule_delayed_work(&linkwatch_work, delay); 144} 145 146 147static void linkwatch_do_dev(struct net_device *dev) 148{ 149 /* 150 * Make sure the above read is complete since it can be 151 * rewritten as soon as we clear the bit below. 152 */ 153 smp_mb__before_atomic(); 154 155 /* We are about to handle this device, 156 * so new events can be accepted 157 */ 158 clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); 159 160 rfc2863_policy(dev); 161 if (dev->flags & IFF_UP) { 162 if (netif_carrier_ok(dev)) 163 dev_activate(dev); 164 else 165 dev_deactivate(dev); 166 167 netdev_state_change(dev); 168 } 169 /* Note: our callers are responsible for 170 * calling netdev_tracker_free(). 171 */ 172 dev_put(dev); 173} 174 175static void __linkwatch_run_queue(int urgent_only) 176{ 177#define MAX_DO_DEV_PER_LOOP 100 178 179 int do_dev = MAX_DO_DEV_PER_LOOP; 180 struct net_device *dev; 181 LIST_HEAD(wrk); 182 183 /* Give urgent case more budget */ 184 if (urgent_only) 185 do_dev += MAX_DO_DEV_PER_LOOP; 186 187 /* 188 * Limit the number of linkwatch events to one 189 * per second so that a runaway driver does not 190 * cause a storm of messages on the netlink 191 * socket. This limit does not apply to up events 192 * while the device qdisc is down. 193 */ 194 if (!urgent_only) 195 linkwatch_nextevent = jiffies + HZ; 196 /* Limit wrap-around effect on delay. */ 197 else if (time_after(linkwatch_nextevent, jiffies + HZ)) 198 linkwatch_nextevent = jiffies; 199 200 clear_bit(LW_URGENT, &linkwatch_flags); 201 202 spin_lock_irq(&lweventlist_lock); 203 list_splice_init(&lweventlist, &wrk); 204 205 while (!list_empty(&wrk) && do_dev > 0) { 206 207 dev = list_first_entry(&wrk, struct net_device, link_watch_list); 208 list_del_init(&dev->link_watch_list); 209 210 if (!netif_device_present(dev) || 211 (urgent_only && !linkwatch_urgent_event(dev))) { 212 list_add_tail(&dev->link_watch_list, &lweventlist); 213 continue; 214 } 215 /* We must free netdev tracker under 216 * the spinlock protection. 217 */ 218 netdev_tracker_free(dev, &dev->linkwatch_dev_tracker); 219 spin_unlock_irq(&lweventlist_lock); 220 linkwatch_do_dev(dev); 221 do_dev--; 222 spin_lock_irq(&lweventlist_lock); 223 } 224 225 /* Add the remaining work back to lweventlist */ 226 list_splice_init(&wrk, &lweventlist); 227 228 if (!list_empty(&lweventlist)) 229 linkwatch_schedule_work(0); 230 spin_unlock_irq(&lweventlist_lock); 231} 232 233void linkwatch_forget_dev(struct net_device *dev) 234{ 235 unsigned long flags; 236 int clean = 0; 237 238 spin_lock_irqsave(&lweventlist_lock, flags); 239 if (!list_empty(&dev->link_watch_list)) { 240 list_del_init(&dev->link_watch_list); 241 clean = 1; 242 /* We must release netdev tracker under 243 * the spinlock protection. 244 */ 245 netdev_tracker_free(dev, &dev->linkwatch_dev_tracker); 246 } 247 spin_unlock_irqrestore(&lweventlist_lock, flags); 248 if (clean) 249 linkwatch_do_dev(dev); 250} 251 252 253/* Must be called with the rtnl semaphore held */ 254void linkwatch_run_queue(void) 255{ 256 __linkwatch_run_queue(0); 257} 258 259 260static void linkwatch_event(struct work_struct *dummy) 261{ 262 rtnl_lock(); 263 __linkwatch_run_queue(time_after(linkwatch_nextevent, jiffies)); 264 rtnl_unlock(); 265} 266 267 268void linkwatch_fire_event(struct net_device *dev) 269{ 270 bool urgent = linkwatch_urgent_event(dev); 271 272 if (!test_and_set_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state)) { 273 linkwatch_add_event(dev); 274 } else if (!urgent) 275 return; 276 277 linkwatch_schedule_work(urgent); 278} 279EXPORT_SYMBOL(linkwatch_fire_event);