我的理解是,当NIC适配器接收到新数据包时,上半部分处理程序使用DMA将数据从RX缓冲区复制到主内存。我认为这个处理程序不应该在传输完成之前退出或释放 INT 引脚,否则新的数据包会损坏旧的数据包。
但是,DMA一般被认为是异步的,本身需要中断机制来通知CPU数据传输完成。因此我的问题是,DMA 在这里实际上是同步的,还是中断实际上可以在另一个中断处理程序中发生?
最佳答案
一般来说,这种同步是通过 NIC(网络接口(interface)卡)和主机 CPU 之间的环描述符进行的。您将获得数据包路径详细信息here 。我已经在下面解释了环描述符。
编辑:
让我用 Intel's ethernet Controller 来解释一下。如果你看一下第 3.2.3 节,其中给出了RX 描述符格式,它有状态字段,解决数据包所有权问题。关于谁拥有数据包(NIC 驱动程序或 CPU),有两个要点可以避免争用和数据包损坏。
DMA(从 I/O 设备到主机内存):RX/TX 环由“硬件描述符”和“缓冲区”(从主机内存雕刻)组成。当我们说 DMA( Controller 传输数据)时,这发生在从硬件 FIFO 到主机内存的情况。
- 假设我的环形缓冲区(512 字节)不足以容纳完整的传入数据包(1500 或巨型数据包),在这种情况下,数据包可能跨越多个环形缓冲区,并且 EOP(数据包结束)状态字段,表示现在已收到完整的数据包(考虑到所有健全性检查/校验和已完成)。
- 第二个问题是现在谁拥有该数据包(驱动程序或 CPU 以供进一步使用)?现在直到状态标志DD(Descriptor Done)被设置为止,它属于驱动程序。一旦设置完毕,CPU 就可以抓取它进行拾取和戳戳。
这是特定于 RX 路径的。 TX 路径略有不同。
这样考虑,系统中一直存在多个中断(IO、键盘、鼠标等),但是两个中断之间的持续时间非常长,以至于 CPU 可以在中间做很多其他好事情。为了进一步减轻 CPU 的工作负担,DMA 有助于传输数据。因此,如果引发中断并调用子例程,则所有后续中断都可以被屏蔽,因为您已经在该子例程中,但相信我,这些子例程非常小,它们几乎不会消耗任何时间,直到您的下一个数据包到达。这意味着您的数据包到达速度必须高于您的处理速度。
另一个例子:对于路由器/交换机来说,99%的时间任务是路由和交换,因此子程序和中断优先级完全不同,而且它们一直受到大量数据包的轰炸,因此在这种情况下子程序永远不会出现,直到那里又是一个陷入困境的数据包。至少我曾经研究过这样的网络设备。
关于networking - 网卡驱动程序中的 DMA 是否同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45406602/