在Linux网络驱动程序的以下两种情况下,是否有人可以解释是否需要其他同步,例如锁定?我对2.6.32及更高版本的内核感兴趣。
1. .probe VS .ndo_open
在PCI网卡的驱动程序中,net_device
实例通常在.probe()
回调中注册。假设驱动程序在.ndo_open
中指定net_device_ops
回调,执行其他必要的操作,然后调用register_netdev()
。
内核可能会在.ndo_open
之后但在register_netdev()
回调结束之前调用.probe
回调吗?我想是,但也许会有更强大的保证,可以确保在.probe
结束之前就可以打开设备?
换句话说,如果.probe
回调访问了,例如,register_netdev()
和ndo_open
回调访问了net_device结构的私有(private)部分之后,我是否需要使用锁或其他方式来同步这些访问?
2. .ndo_start_xmit VS NAPI调查
对于给定的网络设备,是否可以保证驱动程序提供的.ndo_start_xmit
回调和NAPI poll
回调不会同时执行?
我知道.ndo_start_xmit
至少在禁用BH的情况下执行,并且poll
在softirq中运行,因此在BH上下文中运行。但这仅在本地CPU上序列化这些回调的执行。同一网络设备的.ndo_start_xmit
和poll
是否可以在不同的CPU上同时执行?
如上所述,如果这些回调访问相同的数据,是否需要用锁之类的东西保护数据?
赞赏对内核代码和/或文档的引用。
编辑:
为了检查第一种情况,我进行了一个实验,在e1000驱动程序(内核:3.11-rc1)中对register_netdev()
的调用结束之前添加了1分钟的延迟。我还在.probe
和.ndo_open
回调中添加了调试打印。然后,我加载了e1000.ko,并尝试在延迟结束之前访问它所服务的网络设备(实际上,NetworkManager在我之前执行了该操作),然后检查了系统日志。
结果:是,尽管“竞赛窗口”通常很小,但即使在.ndo_open
结束之前也可以调用.probe
。
第二种情况(.ndo_start_xmit
VS NAPI poll
)对我来说仍然不清楚,我们将不胜感激。
最佳答案
写“.ndo_start_xmit VS NAPI民意调查” qs,这就是我的想法:
在NET_TX_SOFTIRQ上下文中调用网络驱动程序的start-xmit方法-它在softirq ctx本身中。 NAPI接收轮询方法也是如此,但是当然是在NET_RX_SOFTIRQ上下文中。
现在,两个softirq将在任何本地核心上相互锁定-而不是竞争。但是根据设计意图,softirq无疑可以在SMP上并行运行。因此,谁说在两个单独的softirq上下文中运行的这两个方法“.ndo_start_xmit VS NAPI民意测验”将永远不会竞争?
IOW,我猜可能会发生。安全起见,请使用自旋锁来保护全局数据。
而且,随着现代TCP卸载技术变得越来越普遍,GSO也可以在任何时候被调用。
HTH!