接收端缩放版本 2 (RSSv2)

接收端缩放改进了与处理多处理器系统上的网络数据相关的系统性能。 NDIS 6.80 及更高版本支持 RSS 版本 2 (RSSv2) ,它通过按 VPort 提供队列的动态分布来扩展 RSS。

概述

与 RSSv1 相比,RSSv2 缩短了 CPU 负载测量与更新间接表之间的时间。 这可避免在高流量情况下减速。 为此,RSSv2 在处理请求的处理器上下文中以 IRQL = DISPATCH_LEVEL 执行其操作,并且仅对指向当前处理器的一部分间接表条目进行操作。 这意味着 RSSv2 可以在多个处理器上动态分布接收队列,其响应速度比 RSSv1 高得多。

RSSv2 中引入了两个 OID, OID_GEN_RECEIVE_SCALE_PARAMETERS_V2OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES,用于微型端口驱动程序分别设置适当的 RSS 功能和控制间接表。 OID_GEN_RECEIVE_SCALE_PARAMETERS_V2是常规 OID,而 OID_GEN_RSS_SET_INDIRECTION_ENTRIES 是无法返回NDIS_STATUS_PENDING的同步 OID。 有关这些 OID 的详细信息,请参阅其单独的参考页。 有关同步 OID 的详细信息,请参阅 NDIS 6.80 中的同步 OID 请求接口

RSSv2 术语

本主题使用以下术语:

术语 定义
RSSv1 第一代接收端缩放机制。 使用 OID_GEN_RECEIVE_SCALE_PARAMETERS
RSSv2 本主题介绍Windows 10版本 1803 及更高版本中支持的第二代接收端缩放机制。
缩放实体 本机 RSS 模式下的微型端口适配器本身,或 RSSv2 模式下的 VPort。
这儿 间接表条目 (给定缩放实体的 ITE) 。 在 VMQ 模式下,每个 VPort 的 ITE 总数不能超过 NumberOfIndirectionTableEntriesPerNonDefaultPFVPortNumberOfIndirectionTableEntriesForDefaultVPort ,在本机 RSS 情况下不能超过 128。 NumberOfIndirectionTableEntriesPerNonDefaultPFVPortNumberOfIndirectionTableEntriesForDefaultVPortNDIS_NIC_SWITCH_CAPABILITIES 结构的成员。
缩放模式 控制 ITE 在运行时的处理方式的 per-VPort vmswitch 策略。 这可能是静态的, (由于负载变化) 或 dyanmic (扩展和合并而没有 ITE 移动,具体取决于当前流量负载) 。
队列 基础硬件对象 (支持 ITE 的队列) 。 根据硬件和间接表,配置队列可能支持多个 ITE。 队列总数(包括默认队列使用的队列)不能超过通常由管理员设置的预配置限制。
默认处理器 接收无法计算哈希的数据包的处理器。 每个 VPort 都有一个默认处理器。
主处理器 在 VPort 创建期间指定为 NDIS_NIC_SWITCH_VPORT_PARAMETERS 结构的 ProcessorAffinity 成员的处理器。 可以在运行时更新此处理器,并指定 VMQ 流量的定向位置。
源 CPU ITE 当前映射到的处理器。
目标 CPU 使用 RSSv2) 将 ITE 重新映射到的处理器 (。
执行组件 CPU 正在对其发出 RSSv2 请求的处理器。

在微型端口驱动程序中宣传 RSSv2 功能

微型端口驱动程序通过使用 NDIS_RSS_CAPS_SUPPORTS_INDEPENDENT_ENTRY_MOVE标志设置 NDIS_RECEIVE_SCALE_CAPABILITIES 结构的 CapabilitiesFlags 成员来播发 RSSv2 支持。 若要启用 RSSv2 的 CPU 负载均衡功能,以及为非默认 VPorts (VMQs ) 启用 RSSv1 动态均衡的NDIS_RECEIVE_FILTER_DYNAMIC_PROCESSOR_AFFINITY_CHANGE_SUPPORTED标志,则需要此功能。

注意

上层协议假定可以为 RSSv2 微型端口驱动程序移动默认 VPort 的主处理器。

如果微型端口适配器未播发 RSSv2 功能,则即使请求这些 VPort 执行动态分布,所有已启用 VMQ 的 VPort 仍保持静态分布模式。 用于配置 RSS 参数的 RSSv1 OID OID_GEN_RECEIVE_SCALE_PARAMETERS用于这些仍处于静态分布模式的 VPort。

微型端口驱动程序只需实现一个 RSS 控制机制 - RSSv1 或 RSSv2。 如果驱动程序播发 RSSv2 支持,则如果需要配置每个 VPort 分布,NDIS 会将 RSSv1 OID 转换为 RSSv2 OID。 微型端口驱动程序必须支持两个新的 OID,并修改 RSSv1 OID_GEN_RECEIVE_SCALE_PARAMETERS OID 的行为,如下所示:

处理 RSSv2 OID

OID_GEN_RECEIVE_SCALE_PARAMETERS 仅用于查询给定缩放实体的当前 RSS 参数。 在 RSSv1 中,此 OID 用于设置参数。 对于支持 RSSv2 的微型端口驱动程序,NDIS 会自动为驱动程序执行此角色转换,并改为发出以下两个 OID 来设置参数。

OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 是常规 OID,其处理方式与 RSSv1 中处理OID_GEN_RECEIVE_SCALE_PARAMETERS OID 相同。 此 OID 对于 NDIS 6.80 之前 (LDF) 的 NDIS 轻型筛选器驱动程序不可见。

但是,OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES是无法返回NDIS_STATUS_PENDING的同步 OID。 必须在源自 OID 的处理器上下文中执行并完成此 OID。 与 OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 一样,NDIS 6.80 之前的 NDIS LDF 也不可见。 不允许 NDIS 6.80 及更高版本中的 LDF 延迟此 OID 或移动到另一个处理器。 其有效负载包含一组简单的“移动 ITE”操作,其中每个操作都包含一个命令,用于将缩放实体的单个 ITE 移动到不同的目标 CPU。 数组的元素可以引用 VPorts) (不同的缩放实体。

每种类型的 NDIS 驱动程序、微型端口、筛选器和协议都有支持同步 OID 请求接口的入口点:

NDIS 驱动程序类型 同步 OID 处理程序 () 用于引发同步 OID 的函数
微型端口 MiniportSynchronousOidRequest 空值
筛选器 NdisFSynchronousOidRequest
协议 空值 NdisSynchronousOidRequest

RSS 状态转换、ITE 更新和主/默认处理器

转向参数

在 RSSv2 中,使用不同的参数将流量定向到正确的 CPU,具体取决于 RSS 状态 (启用或禁用) 。 禁用 RSS 时,仅主处理器用于定向流量。 启用 RSS 后,默认处理器和所有 ITE 都用于定向流量。 这些 指导参数 标记为“活动”或“非活动”,如下表汇总:

转向参数 RSS 已禁用 已启用 RSS
主处理器 活动 非活动
默认处理器 非活动 活动
ITE[0..N] 非活动 活动

当转向参数处于 活动 状态时,它会引导流量。 从使参数 处于非活动状态的 RSS 状态转换开始,微型端口驱动程序必须跟踪参数的更改,直到反向转换再次激活参数。 这意味着,在为该缩放实体禁用 RSS 时,微型端口驱动程序需要跟踪对默认处理器和间接表条目的所有更新。 启用 RSS 后,默认处理器和间接表的当前跟踪状态应生效。

例如,假设已启用软件 vRSS 的情况。 在这种情况下,间接寻址表已存在于上层协议中,并由上层软件传播代码主动使用。 如果在硬件 RSS 启用期间,在向硬件发出并执行用于 移动 间接表条目的更新之前,所有条目都开始指向主处理器,则主处理器可能会遇到短暂的卡住。 如果微型端口驱动程序跟踪了默认处理器和 ITE 信息,它可以将流量定向到上层已经预期到的位置。

请注意,虽然微型端口驱动程序必须跟踪非活动转向参数的所有更新,但它们应延迟对这些参数的验证,直到 RSS 状态更改尝试使这些参数 处于活动状态。 例如,在禁用硬件 RSS 时软件传播的情况下,上层协议可以使用任何处理器来传播 (包括适配器的 RSS 集) 外部。 上层确保在 RSS 状态转换时,所有 非活动 参数对新的 RSS 状态有效。 但是,如果微型端口导航器发现任何跟踪 的非活动 转向参数无效,则仍应验证参数,并使 RSS 状态转换失败。

初始状态和转向参数更新

下表描述了创建 ((例如,在创建 VPort 后) )后缩放实体的初始状态,以及如何更新参数:

参数 说明
主处理器
默认处理器
间接寻址表
  • NumberOfIndirectionTableEntries 设置为 1
  • 唯一的条目是使用 VPort 创建期间指定的 相关性 处理器进行初始化的。
  • 可以使用 OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID 进行更新。

使用OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES) (ITE 和主/默认处理器汇报从相应条目当前指向的处理器调用。 对于给定的 VPort,上层可确保在以下情况下不会发出任何用于移动 ITE 或设置主/默认处理器的OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID:

  1. OID_GEN_RECEIVE_SCALE_PARAMETERS_V2正在进行中。
  2. 启动 VPort 删除序列后。 例如,上层仅在最后一个用于移动 ITE 的 OID 完成后发出设置筛选器 OID。

RSS 禁用

在 RSS 禁用期间,上层协议可能会选择将所有 ITE 指向主处理器,然后发出 OID 以禁用 RSS,或者选择按原样保留间接表并禁用 RSS。 在任一情况下,接收流量都应以主处理器为目标。

RSSv2 保留了 RSSv1 的要求,该要求允许上层协议在不首先禁用 RSS 的情况下删除 VPort。 上层可以将 VPort 上的接收筛选器设置为零,从而确保没有接收流量流经 VPort,然后继续删除 VPort 而不禁用 RSS。 上层保证在删除 VPort 期间或之后不会发出OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID。

在 RSS 禁用和 VPort 删除期间,微型端口驱动程序应处理由于以前的队列移动而可能存在的任何挂起的内部操作。

RSSv2 固定

上层协议可确保在执行管理功能或 ITE 移动之前不违反重要固定变量。 例如:

  1. 在减少队列数之前,上层确保间接表引用的处理器数不会超过 VPort 的新队列数。
  2. 上层不应请求违反 VPort 当前配置的队列数的间接表更新。 微型端口驱动程序应强制执行此操作并返回失败。
  3. 在更改 VMMQ-RESTRICTED 适配器的间接表条目数之前,上层确保间接表的内容规范化为 2 的幂。

OID_GEN_RECEIVE_SCALE_PARAMETERS_V2

OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES

NDIS 6.80 中的同步 OID 请求接口