EVT_NET_ADAPTER_RECEIVE_SCALING_SET_INDIRECTION_ENTRIES回调函数 (netreceivescaling.h)
EvtNetAdapterReceiveScalingSetIndirectionEntries 回调函数由客户端驱动程序实现,以执行接收端缩放 (RSS) 间接表条目到新接收队列的移动。
语法
EVT_NET_ADAPTER_RECEIVE_SCALING_SET_INDIRECTION_ENTRIES EvtNetAdapterReceiveScalingSetIndirectionEntries;
NTSTATUS EvtNetAdapterReceiveScalingSetIndirectionEntries(
[_In_] NETADAPTER Adapter,
[_Inout_] NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES *IndirectionEntries
)
{...}
参数
[_In_] Adapter
客户端驱动程序在上一次调用 NetAdapterCreate 中获取的 NETADAPTER 对象。
[_Inout_] IndirectionEntries
指向表示间接表 的NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES 结构的指针。
返回值
如果移动操作成功,则返回STATUS_SUCCESS。 否则,返回相应的 NTSTATUS 错误代码。
注解
通过设置 NET_ADAPTER_RECEIVE_SCALING_CAPABILITIES 结构的相应成员,然后调用 NetAdapterSetReceiveScalingCapabilities 来注册此回调函数的实现。 客户端驱动程序通常在启动 Net 适配器时调用 NetAdapterSetReceiveScalingCapabilities ,然后再调用 NetAdapterStart。
当协议驱动程序需要在 RSS 中重新平衡处理器工作负载时,它首先计算每个间接表条目到新处理器的新映射。 然后,协议将此信息传递给 NetAdapterCx,后者在内部将处理器编号映射到 NIC 接收队列 ID。 NetAdapterCx 将新的间接表(其中条目映射到接收队列 ID )存储在NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES 结构中,并在调用驱动程序的 EvtNetAdapterReceiveScalingSetIndirectionEntries 回调函数时将此结构传递给 NIC 客户端驱动程序。
在此回调中,客户端驱动程序将 NIC 的间接表中的每个条目移动到指定的接收队列。 NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES 数组中的每个NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRY结构都包含表中该条目的哈希索引、要向其分配条目的新接收队列,以及指示单个移动是否成功的状态字段。
将索引条目分配给硬件接收队列的功能取决于每个 NIC 的设计。 例如,某些 NIC 客户端驱动程序可能会将自己的 ID 分配给与 NetAdapterCx 分配的 ID 不同的每个接收队列,因此它们必须先将提供的队列 ID 转换为自己的队列 ID,然后再重新分配间接表条目。 其他 NIC 可能具有一个压缩的间接表,该表的大小不同于系统维护的间接表,因此这些 NIC 的客户端驱动程序在分配条目时需要计算其硬件间接表的正确索引。 有关第二个示例的代码示例,请参阅 Realtek Github 示例驱动程序。
示例
此简单示例假定接收队列与处理器的比率为 1:1,因此 NIC 的间接表的大小与系统的间接表大小相同。
NTSTATUS
MyEvtNetAdapterReceiveScalingSetIndirectionEntries(
_In_ NETADAPTER Adapter,
_Inout_ PNET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES IndirectionEntries
)
{
// Get the adapter's context to retrieve the address of the hardware indirection table
PMY_NET_ADAPTER_CONTEXT adapterContext = GetMyAdapterContext(Adapter);
// Assign each indirection table entry to the specified receive queue
for(size_t i = 0; i < IndirectionEntries->Count; i++)
{
// Get the queue ID from its context
const ULONG queueId = GetMyRxQueueContext(IndirectionEntries->Entries[i].Queue)->QueueId;
// Get the hash index for this entry
const UINT32 index = IndirectionEntries->Entries[i].Index;
// Assign the new queue ID for this index in the indirection table and record success
IndirectionEntries->Entries[i].Status = MySetIndirectionTableEntry(adapterContext->HardwareInfo->RssIndirectionTable[index],
queueId
);
}
return STATUS_SUCCESS;
}
要求
要求 | 值 |
---|---|
目标平台 | 通用 |
最低 KMDF 版本 | 1.25 |
最低 UMDF 版本 | 2.33 |
标头 | netreceivescaling.h (包括 netadaptercx.h) |
IRQL | DISPATCH_LEVEL |
另请参阅
NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES