当前位置:   article > 正文

JJJ:netdev_run_todo

JJJ:netdev_run_todo

net/core/dev.c

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 }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/434502
推荐阅读
相关标签
  

闽ICP备14008679号