heidsoft / devops

devops 经验总结实践与产品化
81 stars 44 forks source link

mellanox 迈络思光纤网卡偶发超时 #71

Open heidsoft opened 1 year ago

heidsoft commented 1 year ago

https://forums.developer.nvidia.com/t/netdev-watchdog-eth0-mlx5-core-transmit-queue-timed-out/262453 https://access.redhat.com/solutions/4434241 https://gitee.com/openeuler/kernel/issues/I7PN3U?from=project-issue https://download.lenovo.com/servers/mig/2021/09/06/54624/mlnx-lnvgy_dd_nic_cx.3.ib-5.0-2.1.8.0-0_rhel8_x86-64.pdf image https://www.h3c.com/cn/BizPortal/DownLoadAccessory/AccessoryDetail.aspx?ID=8b5b2f51-0c4b-46d2-b7fc-24a9dc439ec6 https://www.coverfire.com/articles/queueing-in-the-linux-network-stack/ https://lkml.kernel.org/netdev/1546266733-9512-11-git-send-email-eranbe@mellanox.com/

heidsoft commented 1 year ago

image https://docs.kernel.org/admin-guide/tainted-kernels.html 根据提供的信息,内核信息报告如下:

关于内核编译选项的说明:

关于ksoftirqd/38进程的说明:

关于内核状态的说明:

内核的tainted机制是Linux内核中的一种机制,用于标记内核的运行状态。当内核的某些部分在运行过程中发生了一些不正常的情况,就会被标记为tainted状态。

内核的tainted状态可以通过/proc/sys/kernel/tainted文件来查看,其内容是一个整数,每个位代表一种不同的异常情况。下面是一些常见的tainted状态位及其含义:

  1. TAINT_PROPRIETARY_MODULE(1):内核中加载了闭源的模块。
  2. TAINT_FORCED_MODULE(2):内核中加载了强制的模块。
  3. TAINT_CPU_OUT_OF_SPEC(4):CPU执行了一个不符合规范的操作。
  4. TAINT_FORCED_RMMOD(8):强制从内核中卸载了模块。
  5. TAINT_MACHINE_CHECK(16):机器检查异常。
  6. TAINT_BAD_PAGE(32):内核中存在一个错误的页面。
  7. TAINT_USER(64):用户空间代码触发了一个异常。
  8. TAINT_DIE(128):内核发生了一个致命错误。
  9. TAINT_OOT_MODULE(256):加载了一个来自外部树的模块。

当内核的tainted状态发生变化时,会生成一条taint信息,可以通过dmesg命令查看。这些信息可以帮助开发人员定位和解决问题。

需要注意的是,tainted机制并不是一种完全可靠的诊断工具,它只是作为一种指示当前内核状态的一种方式。在调试和分析内核问题时,还需要结合其他工具和方法来进行全面的诊断。

heidsoft commented 1 year ago

linux 内核4.19.91-27.1 ,网络调度模块,cloud-kernel-4.19.91-27.1/net/sched/sch_generic.c

static void dev_watchdog(struct timer_list *t)
{
        struct net_device *dev = from_timer(dev, t, watchdog_timer);

        netif_tx_lock(dev);
        if (!qdisc_tx_is_noop(dev)) {
                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);
                                trans_start = txq->trans_start;
                                if (netif_xmit_stopped(txq) &&
                                    time_after(jiffies, (trans_start +
                                                         dev->watchdog_timeo))) {
                                        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);
}