赞
踩
由unregister_netdev->rtnl_unlock触发
8986 void netdev_run_todo(void) 8987 { 8988 struct list_head list; 8989 8990 /* Snapshot list, allow later requests */ 8991 list_replace_init(&net_todo_list, &list); 把net_todo_list转移到list 8992 8993 __rtnl_unlock(); 8994 8995 8996 /* Wait for rcu callbacks to finish before next phase */ 8997 if (!list_empty(&list)) 8998 rcu_barrier(); 8999 9000 while (!list_empty(&list)) { 开始遍历这个表,这个表只会有一个元素 9001 struct net_device *dev 找到列表元素对应的net_device 9002 = list_first_entry(&list, struct net_device, todo_list); 9003 list_del(&dev->todo_list); 9004 9005 if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) { 9006 pr_err("network todo '%s' but state %d\n", 9007 dev->name, dev->reg_state); 9008 dump_stack(); 9009 continue; 9010 } 9011 9012 dev->reg_state = NETREG_UNREGISTERED; 9013 9014 netdev_wait_allrefs(dev); 9015 9016 /* paranoia */ 9017 BUG_ON(netdev_refcnt_read(dev)); 9018 BUG_ON(!list_empty(&dev->ptype_all)); 9019 BUG_ON(!list_empty(&dev->ptype_specific)); 9020 WARN_ON(rcu_access_pointer(dev->ip_ptr)); 9021 WARN_ON(rcu_access_pointer(dev->ip6_ptr)); 9022 #if IS_ENABLED(CONFIG_DECNET) 9023 WARN_ON(dev->dn_ptr); 9024 #endif 9025 if (dev->priv_destructor) 9026 dev->priv_destructor(dev); 9027 if (dev->needs_free_netdev) 9028 free_netdev(dev); 9029 9030 /* Report a network device has been unregistered */ 9031 rtnl_lock(); 9032 dev_net(dev)->dev_unreg_count--; 9033 __rtnl_unlock(); 9034 wake_up(&netdev_unregistering_wq); 9035 9036 /* Free network device */ 9037 kobject_put(&dev->dev.kobj); 9038 } 9039 } 8901 /** 8902 * netdev_wait_allrefs - wait until all references are gone. 8903 * @dev: target net_device 8904 * 8905 * This is called when unregistering network devices. 8906 * 8907 * Any protocol or device that holds a reference should register 8908 * for netdevice notification, and cleanup and put back the 8909 * reference if they receive an UNREGISTER event. 8910 * We can get stuck here if buggy protocols don't correctly 8911 * call dev_put. 8912 */ 8913 static void netdev_wait_allrefs(struct net_device *dev) 8914 { 8915 unsigned long rebroadcast_time, warning_time; 8916 int refcnt; 8917 8918 linkwatch_forget_dev(dev); 8919 8920 rebroadcast_time = warning_time = jiffies; 8921 refcnt = netdev_refcnt_read(dev); 把每个cpu对该网卡的引用都加起来 8922 8923 while (refcnt != 0) { 只要引用计数不为0,就一直循环 8924 if (time_after(jiffies, rebroadcast_time + 1 * HZ)) { 8925 rtnl_lock(); 8926 8927 /* Rebroadcast unregister notification */ 8928 call_netdevice_notifiers(NETDEV_UNREGISTER, dev); 8929 8930 __rtnl_unlock(); 8931 rcu_barrier(); 8932 rtnl_lock(); 8933 8934 if (test_bit(__LINK_STATE_LINKWATCH_PENDING, 8935 &dev->state)) { 8936 /* We must not have linkwatch events 8937 * pending on unregister. If this 8938 * happens, we simply run the queue 8939 * unscheduled, resulting in a noop 8940 * for this device. 8941 */ 8942 linkwatch_run_queue(); 8943 } 8944 8945 __rtnl_unlock(); 8946 8947 rebroadcast_time = jiffies; 8948 } 8949 8950 msleep(250); 8951 8952 refcnt = netdev_refcnt_read(dev); 8953 8954 if (refcnt && time_after(jiffies, warning_time + 10 * HZ)) { 8955 pr_emerg("unregister_netdevice: waiting for %s to become free. Usage count = %d\n", 8956 dev->name, refcnt); 8957 warning_time = jiffies; 8958 } 8959 } 8960 } 用于从全局链表中移除与指定网络设备`dev`相关的链路状态监视事件,并在移除后清理相关资源。 211 void linkwatch_forget_dev(struct net_device *dev) 212 { 213 unsigned long flags; 214 int clean = 0; 215 216 spin_lock_irqsave(&lweventlist_lock, flags); flags用于保存中断状态,并获取自旋锁 217 if (!list_empty(&dev->link_watch_list)) { 如果不是空链表,则表示该设备有待处理的链路状态监视事件。 218 list_del_init(&dev->link_watch_list); 219 clean = 1; 设置变量clean为1,表示设备的链路状态监视事件已被清理。 220 } 221 spin_unlock_irqrestore(&lweventlist_lock, flags); 恢复中断状态,释放自旋锁 222 if (clean) 检查clean变量是否为1。如果是,说明成功清理了网络设备的链路状态监视事件 223 linkwatch_do_dev(dev); 调用linkwatch_do_dev函数进一步处理设备的链路状态变化。 224 } 把每个cpu对该网卡的引用都加起来 8891 int netdev_refcnt_read(const struct net_device *dev) 8892 { 8893 int i, refcnt = 0; 8894 8895 for_each_possible_cpu(i) 8896 refcnt += *per_cpu_ptr(dev->pcpu_refcnt, i); 8897 return refcnt; 8898 } 处理网络设备的链路状态变化 144 static void linkwatch_do_dev(struct net_device *dev) 145 { 146 /* 147 * Make sure the above read is complete since it can be 148 * rewritten as soon as we clear the bit below. 149 */ 150 smp_mb__before_atomic(); 确保之前对设备链路状态的读取操作完成,这里插入了一条内存屏障指令 151 152 /* We are about to handle this device, 153 * so new events can be accepted 154 */清除设备状态标志__LINK_STATE_LINKWATCH_PENDING,表示已经开始处理此设备的链路状态变化。 155 clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); 156 157 rfc2863_policy(dev); 遵循RFC 2863标准,处理网络设备的连通性状态信息。 158 if (dev->flags & IFF_UP) { 检查设备是否已启动(IFF_UP标志已设置) 159 if (netif_carrier_ok(dev)) 链路载波(carrier)可用(netif_carrier_ok返回真) 160 dev_activate(dev); 激活设备 161 else 162 dev_deactivate(dev); 163 164 netdev_state_change(dev);通知网络子系统设备的链路状态发生了变化 165 } 166 dev_put(dev); 167 } 通知网络子系统设备的链路状态发生了变化:一个是通知链通知,一个是netlink消息 1342 void netdev_state_change(struct net_device *dev) 1343 { 1344 if (dev->flags & IFF_UP) { 1345 struct netdev_notifier_change_info change_info = { 1346 .info.dev = dev, 1347 }; 1348 1349 call_netdevice_notifiers_info(NETDEV_CHANGE, 1350 &change_info.info); 1351 rtmsg_ifinfo(RTM_NEWLINK, dev, 0, GFP_KERNEL); 1352 } 1353 } 激活网络设备,使其能够正常发送和接收数据包 1114 void dev_activate(struct net_device *dev) 1115 { 1116 int need_watchdog; 1117 1118 /* No queueing discipline is attached to device; 1119 * create default one for devices, which need queueing 1120 * and noqueue_qdisc for virtual interfaces 1121 */ 1122 1123 if (dev->qdisc == &noop_qdisc) 1124 attach_default_qdiscs(dev); 1125 检查网络设备的链路载波(carrier)状态是否正常。链路未就绪(netif_carrier_ok返回假),则延迟设备的激活,直到链路恢复正常。 1126 if (!netif_carrier_ok(dev)) 1127 /* Delay activation until next carrier-on event */ 1128 return; 1129 1130 need_watchdog = 0;遍历网络设备的所有发送队列,并调用transition_one_qdisc函数处理每个队列 1131 netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog); 1132 if (dev_ingress_queue(dev))如果设备启用了入口(ingress)队列,也会调用transition_one_qdisc处理入口队列 1133 transition_one_qdisc(dev, dev_ingress_queue(dev), NULL); 1134 1135 if (need_watchdog) { 1136 netif_trans_update(dev); 更新开始时间戳 1137 dev_watchdog_up(dev); 开启网卡看门狗 1138 } 1139 } 更新开始时间戳 3944 /* legacy drivers only, netdev_start_xmit() sets txq->trans_start */ 3945 static inline void netif_trans_update(struct net_device *dev) 3946 { 3947 struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); 3948 3949 if (txq->trans_start != jiffies) 3950 txq->trans_start = jiffies; 3951 } 492 static void dev_watchdog_up(struct net_device *dev) 493 { 494 __netdev_watchdog_up(dev); 495 } 开启定时器,定时器处理函数见https://blog.csdn.net/engineer0/article/details/137529237 处理函数主要是看发送率是否有超时 480 void __netdev_watchdog_up(struct net_device *dev) 481 { 482 if (dev->netdev_ops->ndo_tx_timeout) { 483 if (dev->watchdog_timeo <= 0) 484 dev->watchdog_timeo = 5*HZ; 485 if (!mod_timer(&dev->watchdog_timer, 486 round_jiffies(jiffies + dev->watchdog_timeo))) 487 dev_hold(dev); 488 } 489 } 见https://blog.csdn.net/engineer0/article/details/137529237 1266 void dev_deactivate(struct net_device *dev) 1267 { 1268 LIST_HEAD(single); 1269 1270 list_add(&dev->close_list, &single); 1271 dev_deactivate_many(&single); 1272 list_del(&single); 1273 }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。