Linux网络驱动程序中的并发:probe()VS ndo_open(),ndo_start_xmit()VS NAPI poll()

Eug*_*ene 5 concurrency networking linux-device-driver linux-kernel

任何人都可以解释在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回调访问,例如,net_device结构的私有部分register_netdev()ndo_open回调访问该部分,我是否需要使用锁或其他方法来同步这些访问?

2. .ndo_start_xmit VS NAPI民意调查

是否有任何保证,对于给定的网络设备,驱动程序提供的.ndo_start_xmit回调和NAPI poll回调永远不会同时执行?

我知道.ndo_start_xmit至少poll在BH禁用的情况下执行并且在softirq中运行,因此,BH上下文.但是这只序列化了这些回调在本地CPU上的执行.是否有可能.ndo_start_xmitpoll在同一网络设备在不同的CPU同时执行?

如上所述,如果这些回调访问相同的数据,是否需要用锁或其他东西保护数据?

欢迎参考内核代码和/或文档.

编辑:

为了检查第一种情况,我进行了一项实验,并register_netdev()在e1000驱动程序(内核:3.11-rc1)调用结束前添加了1分钟的延迟.我还在其中添加了调试打印.probe.ndo_open回调.然后我加载了e1000.ko,并尝试在延迟结束之前访问它服务的网络设备(实际上,NetworkManager在我之前做了),然后检查了系统日志.

结果:是的,.ndo_open即使在.probe"比赛窗口"通常相当小的情况下,甚至可以在结束之前调用.

第二种情况(.ndo_start_xmitVS NAPI poll)对我来说仍然不清楚,任何帮助表示赞赏.

kai*_*wan 4

关于“.ndo_start_xmit VS NAPI poll”qs,我的想法是这样的:网络驱动程序的 start-xmit 方法在 NET_TX_SOFTIRQ 上下文中调用 - 它位于softirq ctx 本身中。NAPI 接收轮询方法也是如此,但当然是在 NET_RX_SOFTIRQ 上下文中。

现在,两个软中断将在任何本地核心上相互锁定(而不是竞争)。但根据设计意图,软中断当然可以在 SMP 上并行运行;因此,谁能说这两种方法(“.ndo_start_xmit VS NAPI poll”)在两个单独的软中断上下文中运行,永远不会竞争?IOW,我想这可能会发生。为了安全起见,使用自旋锁来保护全局数据。

此外,随着现代 TCP 卸载技术变得越来越流行,GSO 也可以在任何时候被调用。哈!