【问题标题】:who does Napi scheduling谁做 Napi 调度
【发布时间】:2016-05-22 08:19:00
【问题描述】:
我在阅读网络驱动程序中的 NAPI 调度时有疑问。
通常,整个网络处理代码在 softirq 上下文中运行。并且使用 NAPI 轮询机制,驱动程序将在中断到达后轮询数据包。
那么,如果 NAPI 代码也运行在 softirq 上下文中,如何调度它。 (因为,无法调度中断上下文代码)。
以及在网络驱动程序中工作队列的用途是什么。
【问题讨论】:
标签:
linux-kernel
linux-device-driver
scheduler
computer-architecture
smp
【解决方案1】:
NAPI 意义上的调度只是意味着将其标记为需要运行。换句话说,您只需让函数调用说“安排我在 NAPI 软中断中运行”。这会导致您的驱动程序的轮询函数被添加到“需要轮询”设备的列表中,并且它还导致 NAPI 软中断在“退出时”被激活。 p>
所以它通常以这种方式工作。您的驱动程序将您的设备配置为告诉它在将来的某个时间点在某些数据包(理想情况下为多个数据包以分摊开销)准备好处理时中断。与此同时,内核调度普通的用户空间进程......
当您的设备中断时:
- 如果尚未处于内核模式,中断会导致转换到内核模式
- linux 中断处理代码找到驱动程序的中断处理程序并调用它。
- 您的中断处理程序调用
napi_schedule(将您的轮询函数放在列表中并触发软中断。
- 您的中断处理程序返回。
- 就在返回用户模式(或中断之前 CPU 正在执行的任何操作)之前,中断处理代码看到网络软中断需要运行并激活它。
- softirq 调用您的 poll 函数来处理传入的数据包,直到您没有更多的数据包或直到 NAPI“预算”用尽。 (在后一种情况下,softirq 稍后会被
ksoftirqd 线程重新调用[我认为]。)
- 您的驱动程序只有在完成处理所有准备处理数据包的情况下才会在您的设备上重新启用中断。
根据我的经验,工作队列通常仅用于某些需要在可调度上下文中完成的长时间操作(即,在等待某事完成时可以阻塞 [睡眠] 的真实任务上下文)。
例如在intel ixgbe驱动中,如果驱动检测到网卡需要重置,就会触发一个work-queue entry重新初始化网卡。某些操作需要相对较长的睡眠时间,如果您可以让其他任务运行,您不希望将处理器束缚在 softirq 上下文中。也可能有其他原因 - 例如,您需要分配大量内存,这可能需要在任务上下文中进行分配调用。