超时处理dev_watchdog
当watchdog发现网卡处于up状态并且发送队列处于停止时间大于5秒时将触发看门狗机制,
dev_watchdog
先找到停止的队列,然后调用igb_tx_timeout
整个网卡队列做超时处理,igb_tx_timeout
中对网卡做了DOWN、UP的操作。
static void dev_watchdog(unsigned long arg) { struct net_device *dev = (struct net_device *)arg; netif_tx_lock(dev); if (!qdisc_tx_is_noop(dev)) { //txq->qdisc不是noop_qdisc if (netif_device_present(dev) && //网卡设备还存在 netif_running(dev) && // 网卡设备还在运行 netif_carrier_ok(dev)) { //网卡设备在线 int some_queue_timedout = 0; unsigned int i; unsigned long trans_start; for (i = 0; i < dev->num_tx_queues; i++) { struct netdev_queue *txq; txq = netdev_get_tx_queue(dev, i); /* * old device drivers set dev->trans_start */ trans_start = txq->trans_start ? : dev->trans_start; if (netif_xmit_stopped(txq) && //发送队列是停止状态 time_after(jiffies, (trans_start + dev->watchdog_timeo))) { //发送队列停止超过5秒 some_queue_timedout = 1; txq->trans_timeout++; break; } } if (some_queue_timedout) { WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out\n", dev->name, netdev_drivername(dev), i); dev->netdev_ops->ndo_tx_timeout(dev); //超时处理函数 } if (!mod_timer(&dev->watchdog_timer, round_jiffies(jiffies + dev->watchdog_timeo))) dev_hold(dev); } } netif_tx_unlock(dev); dev_put(dev); } static const struct net_device_ops igb_netdev_ops = { .ndo_open = igb_open, .ndo_stop = igb_close, .ndo_start_xmit = igb_xmit_frame, ... ... .ndo_tx_timeout = igb_tx_timeout, ... ... } igb_tx_timeout: schedule_work(&adapter->reset_task); igb_reset_task: netdev_err(adapter->netdev, "Reset adapter\n"); igb_reinit_locked: igb_down igb_up