夜雨聆风学习资料网

ARTICLE · 1326303

基于一个实际排障案例,总结AI在系统类软件开发中的能力边界

基于一个实际排障案例,总结AI在系统类软件开发中的能力边界
在一台旧DELL PC上安装HelloX OS,再加载FTP Server软件,作为一个文件服务器和中转站。因为在Ubuntu和Windows之间共享文件实属麻烦,通过这个FTP Server中转一下方便很多。版本中间源代码也备份到这台服务器上。
前两天上传一个大文件,FTP Server突然卡死,telnet连接不上。到近端用键盘操作,发现HelloX OS交互正常,但已经评ping不通缺省网关。以前还好好的,突然出现这个问题,怀疑网卡驱动程序有问题,于是开启了连续三天的trouble shotting。当然,是在AI(OpenCode + DeepSeek)辅助下。
这个过程很波折,最终也没有定位到原因,而是采取了一个规避措施把问题先绕开。大概率是硬件故障导致,毕竟这个DELL PC已快十年了。这个过程也证明了HelloX OS本身的故障调试、架构可扩展、调度性能等还是很能打的,甚至驱动程序也没找出BUG。
这个排障过程,也更加深切感受到了AI的能力边界,简单总结如下(个人观点):
  1. AI对硬件Specification和Datasheet的理解非常精准、全面。原来需要查阅数千页PDF文档去理解一个参数的含义,现在只需要问AI,直接给出精确回答;
  2. AI对既有代码的理解能力很强,可以通读数十万行代码,找到前后逻辑,并在后续编码或排障中应用。这已超出大部分专业程序员;
  3. AI给出的方案相对完善、契合既有架构。编写的代码质量高,可直接不加修改的编译通过。但为了确保正确性,需要人仔细阅读、理顺逻辑,确认无误后再合入主分支;
  4. 不足之处,就是AI缺乏直觉。一个数十万行代码的工程,资深的维护人员在遇到问题时,往往会根据直觉判断出问题所在(或者大概的范围),然后去细化、确认。AI就缺乏这种直觉,因此很多时候给出的方案就很扯淡,一看就不对。
总之,除了一些深层次的故障还需要人类进行判断,普通故障AI基本可以搞定。但设备驱动、OS内核之类的编程,还是需要人类主导完成。毕竟AI的不确定性、幻觉、缺乏直觉等问题,是无法持续开发和维护大规模系统类软件的。
下面是让AI总结的整个排障过程(原文copy),可以参考。

一、最初现象

  • 平时能 ping 通网关;
  • 一旦有吞吐突发(后来明确是 Windows 往 HelloX FTP server 上传大文件),传几十~几百 KB 后网卡挂住;
  • 上传挂住后:
  • HelloX 不能 ping 网关,Windows 也不能 ping HelloX;
  • 但 127.0.0.1 正常,说明协议栈本身没死;
  • showgif 里 rx/tx 中断计数不涨;
  • 发送队列长期停在 15(后来改成 128 描述符后表现为 TDH 停在某个值不动)。

二、排查过程回顾

1)先查 TX 逻辑

最初怀疑 TX 完成回收依赖 TXDW 中断、没有轮询兜底:
  • _tx_int_handler() 在 pCurrTxHeader == NULL 时提前返回,可能永久失步;
  • TXQE 中断只置标志,不回收描述符;
  • TDT/RDT 初始化成 NUM_DESCRIPTORS,是环外值;
  • 写 TDT 前缺写屏障;
  • ISR while(icr) 无上限。
这些确实是代码问题,但不是本次硬挂的直接原因。

2)加寄存器调试,抓现场

增加了 TDH/TDT、描述符状态、IMS/CTRL/STATUS 等输出。现场看到:
  • TDH == old_tail,硬件停在最老描述符;
  • 描述符 cmd=0x1b(RS 已置位)、status=0(硬件没写回 DD);
  • 链路/PHY 正常(STATUS LU=1、FD=1、1000M);
  • IMS=0xDF,中断没有被人为屏蔽。

3)方向纠正

后来明确:
  • 下载 = HelloX 作为 FTP server 大量发送(TX 重载)→ 正常;
  • 上传 = HelloX 大量接收(RX 重载)→ 挂。
于是重点转向 RX 触发、TX 表现。

4)识别芯片族

8086:15A2 是 Intel I218-LM,属于 e1000e 家族,但驱动 set_mac_type() 只识别 I210/I211 和 82574L,导致它落到 E1000_UNKNOWN,走了 8254x 的 generic 初始化。
这带来几个问题:
  • TXDCTL.Enable、RXDCTL.Enable 没被正确使能;
  • TCTL 还是老的 generic 值;
  • TXDCTL 使用默认阈值,没有 e1000e/PCH 的 PTHRESH/HTHRESH/WTHRESH 配置。

5)确认中断路径

  • 拔插网线 → LSC 中断正常,showint 计数增加,接口 UP→DOWN→UP;
  • 用 ICS 强制制造中断 → 中断正常进入,txqe 计数增加;
  • EICR/GPIE=0,排除 MSI-X/GPIE 路由问题;
  • ICR 读到 0,IMS=0xDF。
结论:中断线、PIC、向量、handler 都是好的。问题不在中断丢失。

6)确认 RX/TX 环语义

通过反汇编 Linux e1000/e1000e 驱动确认:
  • TX TDT 是“下一个要填”(exclusive),空环应为 0;
  • RX RDT 是“最后一个已交给硬件”(inclusive),整环可用应为 N-1,回收后应写刚回收的索引。
而当时驱动是:
  • RX 初始化 RDT=N,回收后写 RDT=rx_tail → RX 环实际只有 1~2 个深(128 环时出现 RDH/RDT=116/117);
  • TX 初始化写成 TDT=N 或 N-1 → 每次 reinit 都可能让硬件误以为有大量空描述符待发。

7)判定为 TX DMA 引擎 hard hang

在故障现场:
  • TDH/TDT=23/43,写 TDT 也不动 TDH;
  • LSC/ICS 中断仍然正常;
  • 描述符 cmd/len 合法,但 status=0。
说明:MAC、PCIe 配置空间、中断逻辑都活着,但 TX DMA 引擎停在某个描述符上不再前进。 这类问题已经超出普通驱动队列错误,属于硬件/DMA/errata 级别。

三、最终确认的代码问题清单

  1. 0x15A2/I218 等 e1000e 芯片被误判为 E1000_UNKNOWN;
  2. e1000e 的 TXDCTL/RXDCTL.Enable 未按芯片族正确设置;
  3. TCTL 使用 generic 值,缺 e1000e 的 RTLC 等配置;
  4. TXDCTL 缺 PTHRESH/HTHRESH/WTHRESH;
  5. RX RDT off-by-one:初始化 N、更新写 rx_tail,导致 RX 环被压成 1~2 个深;
  6. TX TDT 初始化错误:写成 N/N-1,而不是 0;
  7. net_i825xx_tx_init() 在 reinit 时把 tx_drop/txq_full_times 清 0,导致 tx_drop 永远显示 0;
  8. TX 完成回收只依赖中断,_tx_int_handler 有提前返回导致永久失步的路径;
  9. ISR while(icr) 无上限,条件型中断可能拖住处理函数。
其中 5、6 很可能与最初的挂死和 watchdog 频繁复位有关。

四、当前采用的 Workaround

新增 e1000_wd.c watchdog 线程:
  • 每 100ms 检查一次每个 e1000 网卡;
  • 链路 UP 且 old_tail != tx_tail(有未完成 TX)时,观察 TDH 是否前进;
  • 连续 6 次(约 600ms)TDH 不前进 → 触发 __e1000_hw_reinit();
  • 复位时:
  • 屏蔽中断、停 TX/RX、禁用队列;
  • 丢弃所有 TX 队列 buffer(并计入 tx_drop);
  • 清 TX 描述符、清 RX 描述符状态但保留 buffer 地址;
  • 切换 bus master,ResetNic + initializes_hw_bits + rx/tx init;
  • 从 pGenif->genif_ha 恢复 RAL/RAH;
  • 重新开中断、SLU、RX;
  • 不重建 genif,不动 IP/掩码/网关/MAC;
  • 代价:复位期间丢包、TCP 重传,FTP 上传可能报错/重试,但网卡能自动恢复,无需重启系统。
目前 tx_drop 计数已修复:原因是 net_i825xx_tx_init() 在 reinit 时把 tx_drop 清 0,把 __e1000_drop_tx() 刚加的计数抹掉了;移除该清零后计数正常。

五、为什么倾向是硬件问题

你补充的这条现象非常重要:
一旦这台 PC 连接到路由器,原本很稳定的路由器也经常出故障。
这已经不只是“网卡自己收发包异常”,而是 这台 PC 的网口/PHY/板级电气特性开始干扰对端设备。常见原因包括:
  • NIC PHY / 变压器 / 网口磁性元件老化;
  • 主板供电或 PCIe/板载网卡电气特性劣化;
  • 网卡在异常状态下发出畸形帧、过度重传或频繁 link flap,拖垮交换机/路由器端口;
  • 老机器电容/电源老化,负载时电压/信号完整性下降;
  • I218-LM 本身对 ASPM/PCIe 信号质量敏感,硬件老化后更容易触发 DMA/TX hang。
同时,纯软件侧我们已经确认:
  • 中断路径完全正常(LSC/ICS 都能进);
  • 寄存器可读、链路正常;
  • 描述符内容合法;
  • 但 TX DMA 引擎会硬停,且软件写 TDT 也救不回来。
这与“硬件/平台级问题”高度吻合,而不是单纯的驱动 bug。

六、建议的后续动作

1. 临时继续用 watchdog 兜底,但建议:
  • 加 TDH/TDT/old_tail/tx_tail 的复位日志;
  • 区分“真硬件挂(TDH != TDT)”和“回收问题(TDH == TDT)”,后者先 poll 回收而不是整卡复位;
  • 加复位退避,避免 reset 风暴。
2. 把 TDT/RDT 语义修正掉(TDT=0、RDT=N-1、回收后写 freed_idx),这两处即使硬件有问题也应修正,否则会加剧 RX 饥饿和复位后的再次挂死。
3. 硬件验证:
  • 换一根网线、换路由器端口;
  • 用 Linux Live USB 在同一台机器上做持续上传压测,看是否也出现 Detected Hardware Unit Hang / 路由器异常;
  • 如果条件允许,禁用板载 I218,换一块 PCIe/USB 网卡,观察路由器是否恢复稳定;
  • 检查主板电容、电源、网口附近是否有明显老化/发热。
4. 观察路由器侧:如果只有这台 PC 接入时路由器异常,基本可以锁定这台机器的网口/主板硬件问题。
请关注HelloX操作系统公众号,以了解更多内容:

回首页,搜索你想要的文档

在首页搜索框输入关键词,快速定位资料

文库首页搜索指引 立即搜索

相关学习资料