EVT_NET_ADAPTER_RECEIVE_SCALING_SET_INDIRECTION_ENTRIES callback function (netreceivescaling.h)
The EvtNetAdapterReceiveScalingSetIndirectionEntries callback function is implemented by the client driver to perform moves of receive side scaling (RSS) indirection table entries to new receive queues.
Syntax
EVT_NET_ADAPTER_RECEIVE_SCALING_SET_INDIRECTION_ENTRIES EvtNetAdapterReceiveScalingSetIndirectionEntries;
NTSTATUS EvtNetAdapterReceiveScalingSetIndirectionEntries(
[_In_] NETADAPTER Adapter,
[_Inout_] NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES *IndirectionEntries
)
{...}
Parameters
[_In_] Adapter
The NETADAPTER object the client driver obtained in a previous call to NetAdapterCreate.
[_Inout_] IndirectionEntries
A pointer to a NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES structure that represents the indirection table.
Return value
Returns STATUS_SUCCESS if the move operations were successful. Otherwise, returns an appropriate NTSTATUS error code.
Remarks
Register your implementation of this callback function by setting the appropriate member of the NET_ADAPTER_RECEIVE_SCALING_CAPABILITIES structure and then calling NetAdapterSetReceiveScalingCapabilities. Client drivers typically call NetAdapterSetReceiveScalingCapabilities when starting a net adapter, before calling NetAdapterStart.
When a protocol driver needs to rebalance processor workload in RSS, it first calculates a new mapping for each indirection table entry to a new processor. Then the protocol passes this information to NetAdapterCx, which internally maps processor numbers to NIC receive queue IDs. NetAdapterCx stores the new indirection table, with entries mapped to receive queue IDs, in a NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES structure and passes this structure to the NIC client driver when it invokes the driver's EvtNetAdapterReceiveScalingSetIndirectionEntries callback function.
In this callback, client drivers move each entry in their NIC's indirection table to the specified receive queue. Each NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRY structure in the NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES array contains the hash index for that entry in the table, the new receive queue to which to assign the entry, and a status field indicating if that individual move succeeded or not.
The function of assigning index entries to hardware receive queues depends on the design of each NIC. For example, some NIC client drivers might assign their own IDs to each receive queue that are different from the NetAdapterCx-assigned IDs, so they would have to first translate the provided queue IDs to their own queue IDs before reassigning indirection table entries. Other NICs might have a compressed indirection table that differs in size from the system-maintained indirection table, so client drivers of those NICs would need to calculate the correct index into their hardware's indirection table when assigning entries. For a code sample of this second example, see the Realtek Github sample driver.
Example
This simple example assumes a 1:1 ratio of receive queues to processors, so the NIC's indirection table is the same size as the system's indirection table.
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;
}
Requirements
Requirement | Value |
---|---|
Target Platform | Universal |
Minimum KMDF version | 1.25 |
Minimum UMDF version | 2.33 |
Header | netreceivescaling.h (include netadaptercx.h) |
IRQL | DISPATCH_LEVEL |
See also
NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES