You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于NIC驱动ndo_start_xmit中不释放struct sk_buff的技术疑问

NIC驱动ndo_start_xmit()中struct sk_buff释放相关疑问解答

1. 模块生命周期内不释放已使用的struct sk_buff会有什么后果?

  • 内存泄漏持续累积:每个未释放的struct sk_buff会长期占用内核内存,随着数据包发送量增多,内存消耗不断上升,最终可能引发内核OOM(内存溢出),导致系统进程被强制终止甚至直接崩溃。
  • 触发套接字死锁:如果未释放的SKB一直滞留在TX环中,当没有新的TX数据包发送时,等待发送缓冲区空间的套接字会持续阻塞,无法继续发送数据,形成死锁。
  • 违反内核驱动规范:内核明确规定,驱动返回NETDEV_TX_OK后必须在有限时间内释放SKB,长期持有会破坏内核内存管理逻辑,引发其他不可预知的系统异常。

2. Linux内核是否会在超时后或以其他方式释放struct sk_buff?

内核不会主动回收驱动在ndo_start_xmit()返回NETDEV_TX_OK后持有的struct sk_buff。一旦驱动返回NETDEV_TX_OK,该SKB的所有权就完全转移给驱动,后续释放责任由驱动全权承担,内核不会通过超时或其他机制来处理这部分SKB。只有当驱动返回NETDEV_TX_BUSY时,内核才会保留SKB所有权并负责后续处理。

3. 不同Linux内核版本之间的行为是否存在差异?

从内核规范的核心要求来看,各稳定版本的规则保持一致:驱动返回NETDEV_TX_OK后必须自行释放SKB,内核不会主动回收。不过细节实现上存在一些差异:

  • 旧版本内核对内存泄漏的检测机制相对薄弱,未释放SKB引发的问题可能更隐蔽;
  • 部分新版本内核增加了驱动SKB释放情况的监控或警告(如内核调试日志),帮助开发者排查问题;
  • 但关于SKB所有权转移和释放责任的核心规则,从2.6系列到最新的6.x系列内核均无本质变化。

参考Linux内核文档内容

ndo_start_xmit方法不得修改克隆SKB的共享部分。
请记住,一旦从ndo_start_xmit方法返回NETDEV_TX_OK,驱动程序有责任在有限时间内释放该SKB。
例如,这意味着如果没有新的TX数据包发送,TX缓解方案不允许让TX数据包永远留在TX环中而不回收。此错误会导致等待发送缓冲区空间释放的套接字死锁。
如果从ndo_start_xmit方法返回NETDEV_TX_BUSY,则不得保留对该SKB的任何引用,也不得尝试释放它。

内容的提问来源于stack exchange,提问作者Yurij Goncharuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 08:06:16