функция обратного вызова 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

Объект NETADAPTER, полученный драйвером клиента при предыдущем вызове NetAdapterCreate.

[_Inout_] IndirectionEntries

Указатель на структуру NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES , представляющую таблицу косвенного обращения.

Возвращаемое значение

Возвращает STATUS_SUCCESS, если операции перемещения были успешными. В противном случае возвращает соответствующий код ошибки NTSTATUS.

Комментарии

Зарегистрируйте реализацию этой функции обратного вызова, задав соответствующий член структуры NET_ADAPTER_RECEIVE_SCALING_CAPABILITIES , а затем вызвав NetAdapterSetReceiveScalingCapabilities. Клиентские драйверы обычно вызывают NetAdapterSetReceiveScalingCapabilities при запуске сетевого адаптера перед вызовом NetAdapterStart.

Когда драйверу протокола необходимо перераспреждать рабочую нагрузку процессора в RSS, он сначала вычисляет новое сопоставление для каждой записи таблицы косвенного обращения с новым процессором. Затем протокол передает эти сведения в NetAdapterCx, который внутренне сопоставляет номера процессоров с идентификаторами очередей получения сетевой карты. NetAdapterCx сохраняет новую таблицу косвенного обращения с записями, сопоставленными с идентификаторами очередей получения, в NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES структуре и передает эту структуру драйверу клиента сетевой карты при вызове функции обратного вызова EvtNetAdapterReceiveScalingSetIndirectionEntries драйвера.

В этом обратном вызове клиентские драйверы перемещают каждую запись в таблице косвенного обращения сетевого адаптера в указанную очередь получения. Каждая NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRY структура в массиве NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES содержит хэш-индекс для этой записи в таблице, новую очередь получения, которой нужно назначить запись, и поле состояния, указывающее, успешно ли выполнено это отдельное перемещение.

Функция назначения записей индекса очередям получения оборудования зависит от структуры каждой сетевой карты. Например, некоторые клиентские драйверы сетевого адаптера могут назначать свои собственные идентификаторы каждой очереди получения, которые отличаются от идентификаторов, назначаемых NetAdapterCx, поэтому перед переназначением записей таблицы косвенного обращения необходимо сначала преобразовать предоставленные идентификаторы очередей в собственные идентификаторы очередей. Другие сетевые адаптеры могут иметь сжатую таблицу косвенного обращения, размер которых отличается от поддерживаемой системой таблицы косвенного обращения, поэтому клиентским драйверам этих сетевых адаптеров при назначении записей потребуется вычислить правильный индекс в таблице косвенного обращения оборудования. Пример кода этого второго примера см. в примере драйвера Realtek GitHub.

Пример

В этом простом примере предполагается соотношение очередей получения 1:1 к процессорам, поэтому таблица косвенного обращения сетевого адаптера имеет тот же размер, что и таблица косвенного обращения в системе.

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
Верхняя часть netreceivescaling.h (включая netadaptercx.h)
IRQL DISPATCH_LEVEL

См. также раздел

NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRIES

NET_ADAPTER_RECEIVE_SCALING_INDIRECTION_ENTRY

Масштабирование на стороне приема NetAdapterCx