2

我正试图理解Linux内核中的NAPI实现。这些是我基本的疑问。NAPI中断禁用和处理共享中断线

1)NAPI禁止进一步的中断,并处理skbs'使用轮询

  • 谁禁止呢?
  • 中断处理程序是否应该禁用它?

    如果是 - 禁用中断和处理实际轮询完成的SOFTIRQ net_rx_action之间的时间间隔不是太大。

2)默认在下半区使用轮询接收单个帧禁止中断,处理剩余的帧的所有NAPI启用驱动程序? 还是有一个逻辑,只有当帧> 32(连续接收IRQ处理程序中的所有帧)切换到轮询模式?

3)现在来共享IRQ -

  • 发生了什么其它设备的中断,其他设备下半部分可能无法运行,因为这些设备是不存在的poll_list。

回答

5

我写了一本关于网络驱动程序,NAPI等更多内容的全面指南,所以请查看。

至于你的问题:

  1. 设备的IRQ应该启用NAPI后,由驾驶者的IRQ处理程序禁用。是的,有一段时间差距,但应该很小。这是您必须做出权衡决定的一部分:您是否更关心吞吐量或延迟?根据哪个,您可以适当地优化您的网络堆栈。在任何情况下,大多数NIC都允许用户增加(或减少)跟踪传入网络数据的环形缓冲区的大小。所以,暂停是好的,因为数据包稍后将被排队等待处理。

  2. 它取决于驱动程序,但一般情况下,一旦大多数驱动程序在调用napi_schedule时(通常)触发IRQ处理程序,将启用NAPI轮询模式。你可以找到一个演练如何NAPI is enabled for the Intel igb driver here.请注意,IRQ处理程序不一定每个单个数据包被解雇。通过使用名为interrupt coalescing的功能,您可以调整IRQ处理程序在大多数卡上触发的速率。某些网卡可能不支持此选项。

  3. 由于IRQ处理程序在CPU上具有非常高的优先级,所以在IRQ被触发时,其他设备的IRQ处理程序将被执行。 NAPI轮询循环(在SoftIRQ中运行)将在设备IRQ处理的任何CPU上运行。因此,如果您有多个NIC和多个CPU,则可以调整每个NIC的IRQ的IRQ关联性,以防止挨饿特定的NIC。

  4. 至于例子,你在评论中问到:

说NIC 1和NIC 2共享IRQ线,让我们假设NIC 1是低负荷时,NIC 2高负荷和NIC 1接收到中断,NIC 1的驱动程序将禁用中断,直到处理完softirq,将时间间隔称为t1。因此,对于时间t1,NIC 2中断被禁用,对吧?

这取决于驱动程序,但在正常情况下,NIC 1只在IRQ处理程序执行时禁用中断。对napi_schedule的调用告诉softirq代码,如果尚未启动,它应该开始运行。 softirq代码异步运行,因此没有NIC 1不等待softirq被处理。

现在,就共享IRQ而言:再次取决于设备和驱动程序。驱动程序的编写方式应该可以处理共享的IRQ。如果驱动程序禁用正在共享的IRQ,则共享该IRQ的所有设备都不会收到中断。这会很糟糕。有些设备解决这个问题的一种方式是允许驱动程序读/写特定的寄存器,使特定设备停止产生中断。这是首选解决方案,因为它不会阻止其他设备生成相同的IRQ。

当NAPI的IRQ禁用时,意味着驱动程序要求NIC硬件停止发送IRQ。因此,同一行(其他设备)上的其他IRQ仍将继续处理。下面是Intel igb driver通过写入寄存器关闭该器件的IRQ的示例。

+0

谢谢理解1&2,但是3我还不清楚,比如说NIC 1和NIC 2共享IRQ线,让我们假设NIC 1是低负载,NIC 2高负载,NIC 1接收中断,NIC 1的驱动程序将会禁用中断,直到它处理了softirq,并将时间间隔称为t1。因此,对于时间t1,NIC 2中断被禁用,对吧? – Pramod

+0

@Pramod,啊行。我更新了上面的答案 - 让我知道是否有帮助。对不起,我误解你在问什么。您想知道两台共享IRQ的设备如何禁用IRQ以开始使用NAPI而不会阻塞其他设备。是对的吗?如果是这样,我认为我的补充信息解释了这一点。 –

+0

@Pramod我刚刚做了另一次更新并链接到了intel IGB源,因此您可以看到它是如何禁用该NIC的中断的。 –