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 入口点,其中 XxxMiniportFilter ,具体取决于接收请求的驱动程序类型。 如果此入口点看到NDIS_STATUS_PENDING返回状态,则会导致系统 bug 检查。

OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES使用 NDIS_RSS_SET_INDIRECTION_ENTRIES 结构指示微型端口适配器同步执行一组操作,其中每个操作将指定 VPort 的 RSS 间接表的单个条目移动到目标指定的 CPU。

注解

此 OID 必须在发出它的处理器上下文中执行并完成。 微型端口驱动程序必须在将NDIS_STATUS_SUCCESS返回到上层时完全执行此 OID。 这意味着微型端口驱动程序应准备好接收背靠背的 OID 请求,以在第一次移动完成后立即在新处理器上移动多个 ITE NDIS_STATUS_SUCCESS。

提示

完全执行此 OID 意味着微型端口驱动程序必须准备好成功尝试另一个操作来移动 ITE。 它没有规定队列移动后立即指示未完成接收流量的位置,该流量可能位于源 CPU 或目标 CPU 上。

上层协议发出OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES,以将 ITE 和/或主处理器和默认处理器参数设置为指向不同的处理器。

可以为 活动非活动 流量引导参数发出此 OID。 有关指导参数的详细信息,请参阅 接收端缩放版本 2 (RSSv2) 。 对于 处于非活动 状态的参数/ITE,微型端口驱动程序应验证并缓存目标处理器,直到下一个相关 RSS 状态更改 (启用或禁用) 。 此时,缓存的处理器编号将变为 活动状态 ,并用于定向流量。 汇报活动参数 (还必须对其进行验证,) 应立即生效以定向流量。

OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES必须颁发给已清除 NDIS_OID_REQUEST_FLAGS_VPORT_ID_VALID 标志的微型端口适配器。 这是因为数组中的不同元素可能会引用不同的 VPort。

仅在 IRQL == DISPATCH_LEVEL 调用此 OID。

微型端口驱动程序应准备好处理至少与 在 NDIS_NIC_SWITCH_CAPABILITIES 结构中播发的一样多的间接表条目移动操作。 这是在该结构的 NumberOfIndirectionTableEntriesPerNonDefaultPFVPortNumberOfIndirectionTableEntriesForDefaultVPort 成员中定义的,在本机 RSS 模式下为 128

微型端口驱动程序应尝试执行尽可能多的条目,并使用操作结果更新每个NDIS_RSS_SET_INDIRECTION_ENTRYEntryStatus 成员。

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) ,微型端口驱动程序必须处理一个条件,当所有指向 currrent CPU 的 ITE 都移开它时。

如果上述所有检查都通过,微型端口驱动程序应能够无条件地应用新配置,并且必须将每个条目的 EntryStatus 字段设置为NDIS_STATUS_SUCCESS。

通常,此 OID 的处理程序应该非常轻。 它不应调用 NDIS 或操作系统服务,但对于可能的同步操作(如 spinlocks 和 NdisMConfigMSIXTableEntry)而言。

微型端口驱动程序不应调用 NDIS 来指示状态或 PnP 事件。

微型端口驱动程序也不应在此 OID 处理程序的上下文中使用接收/传输完整指示,因为这样做会导致递归。 上层可以从接收或传输指示的上下文调用此 OID。

移动所有间接表条目

微型端口驱动程序应识别并处理将所有间接表条目移出当前 CPU 的特殊请求。 由于 RSSv2 与单个 ITE 移动一起运行,因此微型端口驱动程序必须保证整体操作的原子性。 如果在批处理中处理相应的移动命令数组时遇到错误,微型端口驱动程序应还原已执行的所有命令,并在每命令 EntryStatus 字段中将所有命令标记为“失败”。 上层协议始终要求“移动所有 ITE”批处理包含标记为“成功”的所有命令或标记为“失败”的所有命令,并且将假定流量在移动) 之前或之后遵循生成的状态 (。 如果上层只看到一些标记为“失败”的条目,它将检查系统 bug,并指向微型端口驱动程序作为原因。

为了帮助微型端口驱动程序处理“移动所有 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=2 ITE[0]VPort=1 ITE[0,1]组可能会成功,组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)

另请参阅