警告
本主题中的一些信息与预发行的产品有关,在进行商业发布之前,可能会对其进行大幅修改。 Microsoft对此处提供的信息不作任何明示或暗示的保证。
RSSv2 仅在 Windows 10 版本 1809 中处于预览状态。
OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID 将发送到 RSSv2支持微型端口驱动程序,以执行单个间接表项的移动。 此 OID 是 同步 OID,这意味着它无法返回NDIS_STATUS_PENDING。 它仅作为方法请求颁发,位于 IRQL == DISPATCH_LEVEL。
此调用使用 XxxSynchronousOidRequest 入口点,其中 Xxx 是 微型端口,也可以 筛选器,具体取决于接收请求的驱动程序的类型。 此入口点会导致系统 bug 检查是否看到NDIS_STATUS_PENDING返回状态。
OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES使用 NDIS_RSS_SET_INDIRECTION_ENTRIES 结构指示微型端口适配器同步执行一组作,其中每个作将指定 VPort 的 RSS 间接表的单个条目移到目标 CPU。
言论
此 OID 必须在发出它的处理器上下文中执行并完成。 微型端口驱动程序必须在将NDIS_STATUS_SUCCESS返回到上层时完全执行此 OID。 这意味着,微型端口驱动程序应准备好接收回退 OID 请求,以在首次移动完成NDIS_STATUS_SUCCESS后立即在新处理器上移动多个 ITE。
提示
完全执行此 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。
此 OID 仅在 IRQL == DISPATCH_LEVEL调用。
微型端口驱动程序应准备好处理至少在 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 都移开时处理条件。
如果上述所有检查都通过,微型端口驱动程序应能够无条件地应用新配置,并且必须将每个条目的 EntryStatus 字段设置为NDIS_STATUS_SUCCESS。
通常,此 OID 的处理程序应非常轻量。 它不应调用 NDIS 或作系统服务,而不是针对可能的同步作(如 spinlock 和 NdisMConfigMSIXTableEntry)。
微型端口驱动程序不应调用 NDIS 来指示状态或 PnP 事件。
微型端口驱动程序也不应在此 OID 处理程序的上下文中使用接收/传输完整指示,因为这样做会导致递归。 上层可以从接收或传输指示的上下文中调用此 OID。
移动所有间接表项
微型端口驱动程序应识别并处理将所有间接表条目移出当前 CPU 的特殊请求。 由于 RSSv2 使用单个 ITE 移动作,因此微型端口驱动程序必须保证整体作的原子性。 如果在处理相应移动命令数组时批处理中遇到错误,微型端口驱动程序应还原已执行的所有命令,并将每个命令 EntryStatus 字段中的所有命令标记为“失败”。 上层协议始终要求“移动所有 ITE”批处理包含标记为“成功”的所有命令,或标记为“失败”的所有命令,并且将假定流量遵循生成的状态(移动之前或移动后)。 如果上层只看到一些标记为“失败”的条目,它将 bug 检查系统并指向微型端口驱动程序作为原因。
为了帮助微型端口驱动程序处理“移动所有 ITE”命令,并避免死锁,上层协议组在批处理中的命令成对 SwitchId + VPortId 字段,如下所示:
- 作为“全部移动”命令的一部分,上层希望一起执行的命令将在同一 VPort 中连续放置在整体批处理中。
- 微型端口驱动程序不应尝试以“全部移动”方式执行整个命令批处理,该批处理可能以不同的 VPorts 为目标。 只有以同一 VPort 为目标的命令组(使用相同的 SwitchId + VPortId 对标记)需要执行符合“移动所有”语义。
- 当上层不关心“移动所有”语义时,它可能会将命令交错到同一 VPort,并将命令交错到不同的 VPort(s)。 在这种情况下,如果由于“队列数”冲突而无法执行同一 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)