使用单个硬件接收队列的 RSS

微型端口驱动程序可以支持 RSS 哈希计算和单个接收描述符队列的 NIC 的 RSS。

下图演示了使用单个接收描述符队列进行 RSS 处理。

说明使用单个接收描述符队列进行 RSS 处理的示意图。

在图中,虚线箭头表示接收处理的备用路径。 RSS 无法控制接收初始 ISR 调用的 CPU。

与非 RSS 接收处理不同,基于 RSS 的接收处理分布在多个 CPU 上。 此外,给定连接的处理可以绑定到给定的 CPU。

以下过程针对每个中断重复:

  1. NIC 使用 DMA 使用接收的数据填充缓冲区,并中断系统。

    微型端口驱动程序在初始化期间在共享内存中分配接收缓冲区。

  2. NIC 可以随时填充其他接收缓冲区,但在微型端口驱动程序启用中断之前不会再次中断。

    系统在一次中断中处理的接收缓冲区可以与许多不同的网络连接相关联。

  3. NDIS 在系统确定的 CPU 上 (ISR) 调用微型端口驱动程序的 MiniportInterrupt 函数。

  4. ISR 禁用中断,并请求 NDIS 将延迟过程调用排队 (DPC) 处理接收的数据。

  5. NDIS 在当前 CPU 上 (DPC) 调用 MiniportInterruptDPC 函数。 在 DPC 中:

    1. 微型端口驱动程序使用 NIC 为每个接收的缓冲区计算的哈希值,并将每个接收的缓冲区重新分配给与 CPU 关联的接收队列。
    2. 当前 DPC 请求 NDIS 为与非空接收队列关联的每个其他 CPU 将 DPC 排队。
    3. 如果当前 DPC 在与非空队列关联的 CPU 上运行,则当前 DPC 将处理关联的接收缓冲区,并指示驱动程序堆栈上收到的数据。

    分配队列和排队其他 DPC 需要额外的处理开销。 若要提高系统性能,必须通过更好地利用可用 CPU 来抵消此开销。

  6. 给定 CPU 上的 DPC:

    1. 处理与其接收队列关联的接收缓冲区,并指示驱动程序堆栈上的数据。 有关详细信息,请参阅 指示 RSS 接收数据
    2. 如果中断是最后一个要完成的 DPC,则启用中断。 此中断已完成,进程将再次启动。 驱动程序必须使用原子操作来标识要完成的最后一个 DPC。 例如,驱动程序可以使用 NdisInterlockedDecrement 函数来实现原子计数器。