网卡驱动中的DMA是同步的吗?
Is DMA synchronous in network card drivers?
我的理解是,当网卡适配器接收到新数据包时,top half handler 使用 DMA 将数据从 RX 缓冲区复制到主内存。我认为这个处理程序在传输完成之前不应该退出或释放 INT pin,否则新数据包会破坏旧数据包。
但是,DMA 通常被认为是异步的,它本身需要中断机制来通知CPU数据传输完成。因此我的问题是,DMA 在这里实际上是同步的,还是中断实际上可以在另一个中断处理程序中发生?
通常,此同步通过 NIC(设备驱动程序)和主机 CPU 之间的 环描述符 发生。您将获得数据包路径详细信息 。我已经在下面解释了环描述符。
编辑:
让我用Intel's ethernet Controller解释一下。如果您查看第 3.2.3 节,其中给出了 RX 描述符格式,它具有 status 解决数据包所有权问题的字段。关于谁拥有数据包(NIC 驱动程序或 CPU),有两个要点可以避免争用和数据包损坏。
DMA(从I/O设备到主机内存): RX/TX环由'hardware descriptors'和'buffers'组成(雕刻从主机内存)。当我们说 DMA 时,控制器传输数据,这发生在从硬件 FIFO 到主机内存的过程中。
- 让我们假设我的环形缓冲区(512 字节)不足以容纳完整的传入数据包(1500 或巨型数据包),在这种情况下,数据包可能跨越多个环形缓冲区并且 EOP(End Of Packet) 状态字段,表示现在已收到完整的数据包(考虑到所有完整性 checks/checksums 已经完成)。
- 其次是谁现在拥有数据包(驱动程序或 CPU 以供进一步使用)?现在直到设置状态标志DD(Descriptor Done),它属于驱动程序。一旦设置 CPU 就可以抓住它进行挑选和戳戳。
这是特定于 RX 路径的。 TX 路径略有不同。
这样想,系统中一直在发生多个中断(IO、键盘、鼠标等),但是两个中断之间的持续时间是如此之长,以至于CPU可以做很多事情介于两者之间的其他好东西。为了进一步卸载 CPU 的工作,DMA 有助于传输数据。因此,如果引发中断并调用子例程,则可以屏蔽所有后续中断,因为您已经在该子例程中,但请相信我,这些子例程非常小,它们几乎不会消耗任何时间,直到您的下一个数据包到达。这意味着您的数据包到达速度必须高于您的处理速度。
另一个例子:router/switches 99% 的时间任务是路由和切换,因此子程序和中断优先级是完全不同的,而且它们一直被大量的数据包轰炸,因此在这种情况下子程序将永远不要来,直到有另一个包裹在海湾。至少我曾经研究过这样的网络设备。
我的理解是,当网卡适配器接收到新数据包时,top half handler 使用 DMA 将数据从 RX 缓冲区复制到主内存。我认为这个处理程序在传输完成之前不应该退出或释放 INT pin,否则新数据包会破坏旧数据包。
但是,DMA 通常被认为是异步的,它本身需要中断机制来通知CPU数据传输完成。因此我的问题是,DMA 在这里实际上是同步的,还是中断实际上可以在另一个中断处理程序中发生?
通常,此同步通过 NIC(设备驱动程序)和主机 CPU 之间的 环描述符 发生。您将获得数据包路径详细信息
编辑:
让我用Intel's ethernet Controller解释一下。如果您查看第 3.2.3 节,其中给出了 RX 描述符格式,它具有 status 解决数据包所有权问题的字段。关于谁拥有数据包(NIC 驱动程序或 CPU),有两个要点可以避免争用和数据包损坏。
DMA(从I/O设备到主机内存): RX/TX环由'hardware descriptors'和'buffers'组成(雕刻从主机内存)。当我们说 DMA 时,控制器传输数据,这发生在从硬件 FIFO 到主机内存的过程中。
- 让我们假设我的环形缓冲区(512 字节)不足以容纳完整的传入数据包(1500 或巨型数据包),在这种情况下,数据包可能跨越多个环形缓冲区并且 EOP(End Of Packet) 状态字段,表示现在已收到完整的数据包(考虑到所有完整性 checks/checksums 已经完成)。
- 其次是谁现在拥有数据包(驱动程序或 CPU 以供进一步使用)?现在直到设置状态标志DD(Descriptor Done),它属于驱动程序。一旦设置 CPU 就可以抓住它进行挑选和戳戳。
这是特定于 RX 路径的。 TX 路径略有不同。
这样想,系统中一直在发生多个中断(IO、键盘、鼠标等),但是两个中断之间的持续时间是如此之长,以至于CPU可以做很多事情介于两者之间的其他好东西。为了进一步卸载 CPU 的工作,DMA 有助于传输数据。因此,如果引发中断并调用子例程,则可以屏蔽所有后续中断,因为您已经在该子例程中,但请相信我,这些子例程非常小,它们几乎不会消耗任何时间,直到您的下一个数据包到达。这意味着您的数据包到达速度必须高于您的处理速度。
另一个例子:router/switches 99% 的时间任务是路由和切换,因此子程序和中断优先级是完全不同的,而且它们一直被大量的数据包轰炸,因此在这种情况下子程序将永远不要来,直到有另一个包裹在海湾。至少我曾经研究过这样的网络设备。