platinum 发表于 2005-10-18 11:48

负载过大时,e1000_watchdog 反复 UP、DOWN 的问题

做 NAT 服务器,当负载过大时,总出现

Oct 17 14:56:04 server kernel: e1000: eth0: e1000_watchdog: NIC Link is Down
Oct 17 14:56:08 server kernel: e1000: eth0: e1000_watchdog: NIC Link is Up 100 Mbps Full Duplex
Oct 17 14:56:09 server kernel: e1000: eth0: e1000_watchdog: NIC Link is Down
Oct 17 14:56:15 server kernel: e1000: eth0: e1000_watchdog: NIC Link is Up 100 Mbps Full Duplex

网卡反复 UP、DOWN,甚至导致系统自动重启
这个 e1000_watchdog 是做什么用的?为何有如此现象?如何不让他自动 UP、DOWN ?

yidou 发表于 2005-10-18 12:03

负载过大时,e1000_watchdog 反复 UP、DOWN 的问题


static void
e1000_watchdog(unsigned long data)
{
        struct e1000_adapter *adapter = (struct e1000_adapter *) data;
        struct net_device *netdev = adapter->;netdev;
        struct e1000_desc_ring *txdr = &adapter->;tx_ring;
        unsigned int i;
        uint32_t link;

        e1000_check_for_link(&adapter->;hw);

        if((adapter->;hw.media_type == e1000_media_type_internal_serdes) &&
           !(E1000_READ_REG(&adapter->;hw, TXCW) & E1000_TXCW_ANE))
                link = !adapter->;hw.serdes_link_down;
        else
                link = E1000_READ_REG(&adapter->;hw, STATUS) & E1000_STATUS_LU;

        if(link) {
                if(!netif_carrier_ok(netdev)) {
                        e1000_get_speed_and_duplex(&adapter->;hw,
                                                   &adapter->;link_speed,
                                                   &adapter->;link_duplex);

                        DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s\n",
                             adapter->;link_speed,
                             adapter->;link_duplex == FULL_DUPLEX ?
                             "Full Duplex" : "Half Duplex");

                        netif_carrier_on(netdev);
                        netif_wake_queue(netdev);
                        mod_timer(&adapter->;phy_info_timer, jiffies + 2 * HZ);
                        adapter->;smartspeed = 0;
                }
        } else {
                if(netif_carrier_ok(netdev)) {
                        adapter->;link_speed = 0;
                        adapter->;link_duplex = 0;
                        DPRINTK(LINK, INFO, "NIC Link is Down\n");
                        netif_carrier_off(netdev);
                        netif_stop_queue(netdev);
                        mod_timer(&adapter->;phy_info_timer, jiffies + 2 * HZ);
                }

                e1000_smartspeed(adapter);
        }

        e1000_update_stats(adapter);

        adapter->;hw.tx_packet_delta = adapter->;stats.tpt - adapter->;tpt_old;
        adapter->;tpt_old = adapter->;stats.tpt;
        adapter->;hw.collision_delta = adapter->;stats.colc - adapter->;colc_old;
        adapter->;colc_old = adapter->;stats.colc;
       
        adapter->;gorcl = adapter->;stats.gorcl - adapter->;gorcl_old;
        adapter->;gorcl_old = adapter->;stats.gorcl;
        adapter->;gotcl = adapter->;stats.gotcl - adapter->;gotcl_old;
        adapter->;gotcl_old = adapter->;stats.gotcl;

        e1000_update_adaptive(&adapter->;hw);

        if(!netif_carrier_ok(netdev)) {
                if(E1000_DESC_UNUSED(txdr) + 1 < txdr->;count) {
                        /* We've lost link, so the controller stops DMA,
                       * but we've got queued Tx work that's never going
                       * to get done, so reset controller to flush Tx.
                       * (Do the reset outside of interrupt context). */
                        schedule_work(&adapter->;tx_timeout_task);
                }
        }

        /* Dynamic mode for Interrupt Throttle Rate (ITR) */
        if(adapter->;hw.mac_type >;= e1000_82540 && adapter->;itr == 1) {
                /* Symmetric Tx/Rx gets a reduced ITR=2000; Total
               * asymmetrical Tx or Rx gets ITR=8000; everyone
               * else is between 2000-8000. */
                uint32_t goc = (adapter->;gotcl + adapter->;gorcl) / 10000;
                uint32_t dif = (adapter->;gotcl >; adapter->;gorcl ?
                        adapter->;gotcl - adapter->;gorcl :
                        adapter->;gorcl - adapter->;gotcl) / 10000;
                uint32_t itr = goc >; 0 ? (dif * 6000 / goc + 2000) : 8000;
                E1000_WRITE_REG(&adapter->;hw, ITR, 1000000000 / (itr * 256));
        }

        /* Cause software interrupt to ensure rx ring is cleaned */
        E1000_WRITE_REG(&adapter->;hw, ICS, E1000_ICS_RXDMT0);

        /* Early detection of hung controller */
        i = txdr->;next_to_clean;
        if(txdr->;buffer_info.dma &&
           time_after(jiffies, txdr->;buffer_info.time_stamp + HZ) &&
           !(E1000_READ_REG(&adapter->;hw, STATUS) & E1000_STATUS_TXOFF))
                netif_stop_queue(netdev);

        /* Reset the timer */
        mod_timer(&adapter->;watchdog_timer, jiffies + 2 * HZ);
}


[ 本帖最后由 platinum 于 2005-11-3 14:24 编辑 ]

platinum 发表于 2005-10-18 12:19

负载过大时,e1000_watchdog 反复 UP、DOWN 的问题


if((adapter->;hw.media_type == e1000_media_type_internal_serdes) &&
!(E1000_READ_REG(&adapter->;hw, TXCW) & E1000_TXCW_ANE))
link = !adapter->;hw.serdes_link_down;
else
link = E1000_READ_REG(&adapter->;hw, STATUS) & E1000_STATUS_LU;

这段话什么意思?什么情况会导致 link = 0 ?
如果删除了 else 后面的东西重新编译驱动,会不会有副作用?

colddawn 发表于 2005-10-18 12:56

负载过大时,e1000_watchdog 反复 UP、DOWN 的问题

watchdog这个好像是检测到坏桢认为可能硬件出现故障复位硬件,不过e1000吃不住流量的情况应该不大,估计是线制作的不合格导致大流量时坏桢严重,或者有电气干扰等。

colddawn 发表于 2005-10-18 12:58

负载过大时,e1000_watchdog 反复 UP、DOWN 的问题

对了,ifconfig看一下是不是相应网卡出现很多errors的包

platinum 发表于 2005-10-18 13:11

负载过大时,e1000_watchdog 反复 UP、DOWN 的问题

很奇怪呢,RX-ERR RX-DRP RX-OVR,这三项都是 0
是这样的,这台机器上还运行其他服务,CPU 一直比较高,会不会是没有过多的 CPU 来负责处理数据包造成的?

还有,我如果修改源代码,注释掉硬件复位那段代码可不可以?会不会有副作用?

wheel 发表于 2005-10-18 14:38

负载过大时,e1000_watchdog 反复 UP、DOWN 的问题

cat /proc/interrupts看下是否和这相似,注释掉硬件复位那段代码没问题,
          CPU0       CPU1       CPU2       CPU3
0:347275720347745526340396987340996245    IO-APIC-edgetimer
1:      284      789      878      556    IO-APIC-edgei8042
8:          0          0          0          1    IO-APIC-edgertc
9:          0          0          0          0   IO-APIC-levelacpi
14:          1          0         20         19    IO-APIC-edgeide0
15:      87104   399199       5819   328406    IO-APIC-edgelibata
169:          0          0          0          0   IO-APIC-leveluhci_hcd
177:          0          0          0          0   IO-APIC-leveluhci_hcd
185:          0          0          0          0   IO-APIC-levelehci_hcd
209:   186220    5466568   211081    5950435   IO-APIC-levelioc0
217:   27184131          0          0      157   IO-APIC-leveleth0
225:          0          0   51742411         29   IO-APIC-leveleth1
NMI:          0          0          0          0
LOC: 1376397708 1376397707 1376397706 1376397705
ERR:          0
MIS:          0

platinum 发表于 2005-10-18 14:41

负载过大时,e1000_watchdog 反复 UP、DOWN 的问题


         CPU0
0:    5208209    IO-APIC-edgetimer
1:          2    IO-APIC-edgekeyboard
4:         30    IO-APIC-edgeserial
8:          1    IO-APIC-edgertc
9:          0   IO-APIC-levelacpi
15:   108463    IO-APIC-edgeide1
21:   15700851   IO-APIC-leveleth0
22:   15716884   IO-APIC-leveleth1
NMI:          0
LOC:    5208446
ERR:          0
MIS:          0

这样正常吗?

jackylau 发表于 2005-10-18 15:17

负载过大时,e1000_watchdog 反复 UP、DOWN 的问题

不会是负载过大的原因.我们单位做iptv,负荷比你重多了吧,也是e1000

q1208c 发表于 2005-10-18 15:22

负载过大时,e1000_watchdog 反复 UP、DOWN 的问题

e1000 是千兆的网卡, 100M应该没事呀?
watchdog 好象是用来检测什么东东的一个计时, 我觉得是不是你的 switch 受不了呀? 因为 switch 如果不行了, 网卡一样会认为网络 down 呀.
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 负载过大时,e1000_watchdog 反复 UP、DOWN 的问题