OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES
警告
本主题中的有些信息与预发布产品相关,该产品在商业发行之前可能发生重大更改。 Microsoft 对此处提供的信息不提供任何明示或暗示的保证。
RSSv2 仅在 Windows 10 版本 1809 中提供预览版。
OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID 发送给支持 RSSv2 的微型端口驱动程序,以执行单个间接表项的移动。 此 OID 是同步 OID,这意味着它不能返回 NDIS_STATUS_PENDING。 它仅在 IRQL == DISPATCH_LEVEL 时作为方法请求发出。
此调用使用 XxxSynchronousOidRequest 入口点,其中 Xxx 是微型端口或筛选器,具体取决于接收请求的驱动程序类型。 如果该入口点看到 NDIS_STATUS_PENDING 返回状态,就会进行系统错误检查。
OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES 使用 NDIS_RSS_SET_INDIRECTION_ENTRIES 结构来指示微型端口适配器同步执行一组操作,其中每项操作都将指定 VPort 的 RSS 间接表中的一个条目移动到指定 CPU 的目标。
注解
此 OID 必须在发出它的处理器上下文中执行和完成。 微型端口驱动程序必须在向上层返回 NDIS_STATUS_SUCCESS 时完全执行该 OID。 这意味着微型端口驱动程序应做好准备,在第一次移动结束并显示 NDIS_STATUS_SUCCESS 后,立即接收连续的 OID 请求,以便在新处理器上移动多个 ITE。
提示
完全执行此 OID 意味着微型端口驱动程序必须准备好成功尝试另一个移动 ITE 的操作。 它没有规定队列移动后正在接收流量的指示位置,它既可以是源 CPU,也也可以是目标 CPU。
上层协议发出 OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES,以设置 ITE 和/或主处理器和默认处理器参数,以便指向不同的处理器。
此 OID 可针对活动或非活动流量引导参数进行发布。 有关转向参数的详细信息,请参阅接收端缩放版本 2 (RSSv2)。 对于处于非活动状态的参数/ITE,微型端口驱动程序应验证并缓存目标处理器,直到下一次相关 RSS 状态发生变化(启用或禁用)。 此时,缓存的处理器编号将变为活动,并用于定向流量。 对活动参数(也必须经过验证)的更新应立即生效,以便定向流量。
必须向已清除 NDIS_OID_REQUEST_FLAGS_VPORT_ID_VALID 标记的微型端口适配器发出 OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES。 这是因为数组中的不同元素可能会引用不同的 VPort。
只有在 IRQL == DISPATCH_LEVEL 时才会调用该 OID。
微型端口驱动程序应准备处理至少与在 NDIS_NIC_SWITCH_CAPABILITIES 结构中播发的间接表项移动操作数量相同的移动操作。 这在该结构的 NumberOfIndirectionTableEntriesPerNonDefaultPFVPort 或 NumberOfIndirectionTableEntriesForDefaultVPort 成员中定义,或在本地 RSS 模式中定义为 128。
微型端口驱动程序应尝试执行尽可能多的条目,并用操作结果更新每个 NDIS_RSS_SET_INDIRECTION_ENTRY 的 EntryStatus 成员。
OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES 的 OID 处理程序
OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES 的 OID 处理程序的预期行为如下所示:
- 由于 OID 的同步调用类型,不允许返回 NDIS_STATUS_PENDING。
- 最终完成所有以当前 CPU 为目标的 ITE 移动(之前在远程处理器上启动)。
- 强烈建议微型端口驱动程序执行完整的参数验证传递。 如果不可能,则对数组项进行逐个验证和执行。 微型端口驱动程序应特别检查所有引用对象是否有效:
- 不允许在 ITE 的 EntryStatus 字段中返回 NDIS_STATUS_PENDING。
- 微型端口适配器存在且状态良好。 否则,将条目的 EntryStatus 字段设置为 NDIS_STATUS_ADAPTER_NOT_FOUND、NDIS_STATUS_ADAPTER_NOT_READY 等。
- 每个 VPort 都存在且状态良好。 否则,将条目的 EntryStatus 字段设置为 NDIS_STATUS_INVALID_PORT、NDIS_STATUS_INVALID_PORT_STATE 等。
- 每个间接表项索引都在配置的范围内。 此范围要么是 0xFFFF,要么是在 OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 OID 设置的 [0...NumberOfIndirectionTableEntries - 1] 范围内。 0xFFFF 和 0xFFFE 输入索引具有特殊含义:0xFFFF 定义默认处理器,而 0xFFFE 则定义主处理器。 出错时,处理程序会将条目的 EntryStatus 字段设置为 NDIS_STATUS_INVALID_PARAMETER。
- 上层和微型端口驱动程序希望 ITE 在移动前指向当前处理器(执行组件 CPU)。 换句话说,ITE 无法被远程重定向。 如果不为 true,则将条目的 EntryStatus 字段设置为 NDIS_STATUS_NOT_ACCEPTED。
- 所有目标处理器均有效,并且是微型端口适配器 RSS 集的一部分。 否则,将条目的 EntryStatus 字段设置为 NDIS_STATUS_INVALID_DATA。
- 随后或作为参数验证过程的一部分,对资源情况进行验证。 在 OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 请求期间,验证完整批处理移动(疏散)后使用的队列数不超过 NDIS_RECEIVE_SCALE_PARAMETERS_V2 结构中设置的 NumberOfQueues。 否则,将返回 NDIS_STATUS_NO_QUEUES。 NDIS_STATUS_NO_QUEUES 应用于所有违反队列配置数量的情况。 NDIS_STATUS_RESOURCES 应仅用于指定暂时性内存不足的情况。
- 作为资源检查的一部分,对于每个缩放实体(例如 VPort),当指向当前 CPU 的所有 ITE 都远离该 CPU 时,微型端口驱动程序必须进行处理。
如果上述检查全部通过,微型端口驱动程序应能无条件应用新配置,并且必须将每个条目的 EntryStatus 字段设置为 NDIS_STATUS_SUCCESS。
通常,此 OID 的处理程序应非常轻量。 除了可能的同步操作(如旋转锁和 NdisMConfigMSIXTableEntry)外,它不应调用 NDIS 或操作系统服务。
微型端口驱动程序不应调用 NDIS 来指示状态或 PnP 事件。
微型端口驱动程序也不应在此 OID 处理程序的上下文中使用接收/发送完整指示,否则会导致递归。 上层可在接收或发送指示时调用此 OID。
移动所有间接表项
微型端口驱动程序应能识别并处理将所有间接表项从当前 CPU 移出的特殊请求。 由于 RSSv2 采用单个 ITE 移动操作,因此微型端口驱动程序必须保证整体操作的原子性。 如果在处理相应的移动命令数组时在批处理中间遇到错误,微型端口驱动程序应恢复所有已执行的命令,并在每个命令 EntryStatus 字段中将所有命令标记为“失败”。 上层协议始终希望“移动所有 ITE”批处理包含标记为“成功”的所有命令或标记为“失败”的所有命令,并假定流量遵循所产生的状态(移动前或移动后)。 如果上层只看到一些标记为“失败”的条目,则会对系统进行错误检查,并将原因指向微型端口驱动程序。
为帮助微型端口驱动程序处理“移动所有 ITE”命令并避免发生死锁,上层协议会将批处理中的移动命令按 SwitchId + VPortId 字段成对分组,如下所示:
- 作为“全部移动”命令的一部分,上层希望在同一 VPort 上一起执行的命令将在整个批处理中连续执行。
- 微型端口驱动程序不应尝试以“全部移动”的方式来执行可能针对不同 VPort 的整个批处理命令。 只有以相同 VPort 为目标(标记为相同的 SwitchId + VPortId 对)的命令组才需要按照“全部移动”语义执行。
- 当上层不关心“全部移动”语义时,它可能会将发往同一 VPort 的命令与发往不同 VPort 的命令交错在一起。 在这种情况下,如果向同一 VPort 发出的第二组命令因违反“队列数”规定而无法执行,则微型端口驱动程序会用相应的状态代码 (NDIS_STATUS_NO_QUEUES) 标记该组命令,并由上层负责恢复。
例如,如果上层协议将一系列命令交错在一起,如下所示:
VPort=1 ITE[0,1]
VPort=2 ITE[0]
VPort=1 ITE[2]
微型端口驱动程序不需要尝试以原子方式执行所有四个移动命令,也不需要尝试对 VPort=1
(ITE[0,1,2]
) 执行所有三个移动命令。 它只需要以“全部移动”的方式执行 VPort=1 ITE[0,1]
组,然后执行 VPort=2 ITE[0]
组,再执行 VPort=1 ITE[2]
组。 这三个命令组可能产生不同的结果。 例如,VPort=1 ITE[0,1]
和 VPort=2 ITE[0]
的组可能成功,而 VPort=1 ITE[2]
组可能失败。 结果应反映在每个命令结构的相应 EntryStatus 成员中。 这样,微型端口驱动程序就不需要为整个批处理的安全执行采取预防措施(例如,锁定整个适配器)。 只有那些针对特定 VPort 的命令才需要序列化,可以使用更精细的每个 VPort 锁定,并避免某些死锁。
注意
整组命令条目必须标记为相同的条目状态。
错误条件和状态代码
当发生错误时,此 OID 会返回以下状态代码:
状态代码 | 添加状态 |
---|---|
NDIS_STATUS_INVALID_LENGTH | OID 格式错误。 |
NDIS_STATUS_INVALID_PARAMETER | 标头或 OID 本身(但不包括单个命令条目)中的其他字段包含无效值。 |
要求
版本:Windows 10 版本 1709 标头:Ntddndis.h(包括 Ndis.h)