Поделиться через


Функция NdisMAllocateSharedMemory (ndis.h)

Осторожность

Для процессоров ARM и ARM64 настоятельно рекомендуется, чтобы средства записи драйверов NDIS использовали WDF DMA или WDM DMA вместо NDIS Scatter/Сбор DMA.

Дополнительные сведения о WDF DMA см. в обработке операций DMA в драйверах KMDF.

Дополнительные сведения о WDM DMA см. в дочерних разделах, связанных с DMA, в разделе Управление входными и выходными данными для драйверов.

NdisMAllocateSharedMemory выделяет и сопоставляет диапазон памяти узла, чтобы диапазон памяти был одновременно доступен как из системы узла, так и сетевой карты DMA.

Синтаксис

void NdisMAllocateSharedMemory(
  [in]  NDIS_HANDLE            MiniportAdapterHandle,
  [in]  ULONG                  Length,
  [in]  BOOLEAN                Cached,
  [out] PVOID                  *VirtualAddress,
  [out] PNDIS_PHYSICAL_ADDRESS PhysicalAddress
);

Параметры

[in] MiniportAdapterHandle

Задает входные данные дескриптора для MiniportInitializeEx.

[in] Length

Указывает количество выделенных байтов.

[in] Cached

Этот параметр игнорируется (кэшированная память всегда используется в системах x86 и x64).

[out] VirtualAddress

Указатель на указанную вызывающим переменную, в которой эта функция возвращает базовый виртуальный адрес выделения для использования мини-драйвером. Если NdisMAllocateSharedMemory не может удовлетворить вызывающий объект, он возвращает null, чтобы указать, что память не выделена.

[out] PhysicalAddress

Указатель на указанную вызывающим переменную, в которой эта функция возвращает физический адрес, подходящий для использования сетевым адаптером, который соответствует тому, что возвращается в VirtualAddress, или возвращает NULL.

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

Никакой

Замечания

Примечание Драйвер минипорта должен уже вызывать NdisMRegisterScatterGatherDma или NdisMRegisterDmaChannel, чтобы инициализировать канал точечной или сборной DMA перед вызовом NdisMAllocateSharedMemory.
 
Microsoft Windows Server 2003, Windows XP с пакетом обновления 1 (SP1) и более поздних версий Windows позволяют сетевым адаптерам DMA и подчиненным сетевым адаптерам DMA вызывать NdisMAllocateSharedMemory. Предыдущие выпуски позволяют вызывать только сетевые адаптеры DMA для шины NdisMAllocateSharedMemory. В этих предыдущих выпусках, если MiniportInitializeEx не указали, что сетевой адаптер является главной шиной при вызове NdisMSetMiniportAttributes, NdisMAllocateSharedMemory просто возвращает управление, не пытаясь сделать выделение.

NdisMAllocateSharedMemory предоставляет как сопоставленный диапазон виртуальных адресов, используемый драйвером для доступа к блоку общей памяти, так и диапазону типа NDIS_PHYSICAL_ADDRESS, используемому сетевой картой. Значение, возвращаемое в PhysicalAddress, может быть вдвойне сопоставлено системой. То есть диапазон "физических" адресов, описанный значением PhysicalAddress и Length может быть диапазоном сопоставленных логических адресов, которые не соответствуют физическим адресам узла для выделения на каждой возможной платформе.

NdisMAllocateSharedMemory можно вызывать только из MiniportInitializeEx. Насколько большое выделение для запроса зависит от того, как модуль записи драйверов, зная возможности и функции сетевого адаптера, решает сделать компромисс между следующей производительностью и дилеммой размера:

  • В периоды высокого сетевого трафика минипорт-драйвер не может поддерживать высокую пропускную способность ввода-вывода, если он работает с низким объемом общего пространства памяти для буферов данных, доступных для устройств.

    Например, минипорт-драйвер может указывать, что буферы получения в общей памяти быстрее, чем такие буферы возвращаются из драйверов привязанного протокола при наводнении получения сетевых адаптеров. Если все его общее пространство памяти потребляется выдающимися буферами получения, драйвер минипорта может отключить прерывания приема на сетевом адаптере, пока не будет доступно некоторое общее пространство памяти для буферов получения.

  • С другой стороны, вызов NdisMAllocateSharedMemory с Length, выбранным для прогнозирования некоторого максимального спроса на передачу, делает изображение драйвера более большим и его использование ресурсов довольно неэкономично, за исключением редких периодов очень высокого спроса ввода-вывода. Кроме того, NdisMAllocateSharedMemory может не дать драйверу такой большой блок, если недостаточно системной памяти, принудив драйверу завершить инициализацию.
Минипорт драйвер, предоставляющий функция MiniportSharedMemoryAllocateComplete имеет значительно большую гибкость при разрешении предыдущей производительности и дилеммы размера. MiniportInitializeEx должен выделить только достаточно общего объема памяти с NdisMAllocateSharedMemory для умеренного спроса на операции передачи сети через сетевой адаптер, если драйвер имеет функцию MiniportSharedMemoryAllocateComplete. Такой минипорт-драйвер может вызвать NdisMAllocateSharedMemoryAsyncEx динамически выделять большую общую память в периоды более сильного спроса на передачу сетевого адаптера. Когда высокий спрос на передачу субсидируется, такой драйвер вызывает NdisMFreeSharedMemory, чтобы освободить выделенную им дополнительную память. Обратите внимание, что только сетевые адаптеры DMA для шины могут вызывать NdisMAllocateSharedMemoryAsyncEx и экспортировать MiniportSharedMemoryAllocateComplete. Эта функция не поддерживается для подчиненных сетевых адаптеров DMA.

NdisMAllocateSharedMemory и NdisMAllocateSharedMemoryAsyncEx являются единственными функциями NdisXxx, которые можно вызывать для выделения памяти узла, которая использует виртуальные адреса и сетевой адаптер, который использует соответствующие логические адреса.

Мини-драйвер должен выровнять буферы, выделенные из общей кэшированных памяти, в целой части границы строки кэша узла, чтобы предотвратить разрыв строки кэша во время DMA. Разрыв строки кэша может привести к проблемам целостности данных в драйвере или снижению производительности драйвера (и системы), требуя чрезмерного сброса кэша данных для обеспечения целостности данных. MiniportInitializeEx может вызывать NdisMGetDmaAlignment, чтобы определить границу выравнивания в текущей платформе для буферов, доступных для устройств, которые драйвер настроит в выделенном диапазоне общей памяти.

Минипорт-драйвер должен задать ограничение на то, сколько общего объема памяти он может выделить. Это ограничение зависит от драйвера и должно быть достаточно высоким, чтобы драйвер не иссякнул из буферов. Не устанавливайте ограничение, которое является чрезмерно высоким, так как это может привести к расточительности потребления общей памяти, что может снизить производительность системы.

MiniportInitializeEx также может вызывать NdisSystemProcessorCount перед вызовом NdisMAllocateSharedMemory, если модуль записи драйверов решает выделить большой общий блок памяти на компьютерах с несколькими обработчиками, предполагая, что любой компьютер SMP, скорее всего, будет сетевым сервером с более высокими требованиями сетевой передачи на сетевом адаптере, чем на рабочей станции.

Если его вызов NdisMAllocateSharedMemory завершается ошибкой, MiniportInitializeEx может снова вызвать запрос меньшего выделения. Однако если MiniportInitializeEx не может выделить достаточную общую память для сетевого адаптера, она должна освободить все ресурсы, которые уже выделены и завершаются сбоем.

Если драйвер минипорта впоследствии указывает на получение с помощью NdisMIndicateReceiveNetBufferLists, он должен выделить несколько дескрипторов буфера из буферного пула, которые сопоставляют буферы получения сетевого адаптера в общем блоке памяти.

Если выделенная память кэшируется и, следовательно, необходимо очистить при передаче, драйвер минипорта должен вызывать NdisAllocateMdl, чтобы выделить дескриптор типа NDIS_BUFFER для общего диапазона памяти. Драйвер минипорта должен вызвать KeFlushIoBuffers с этим дескриптором буфера, чтобы выполнить такой сброс.

Если вызывается мини-драйвер NdisMAllocateSharedMemoryAsyncEx или NdisMAllocateSharedMemory, он должен освободить все невыполненные выделения с одним или несколькими вызовами NdisMFreeSharedMemor y при удалении сетевого адаптера, то есть при вызове функции miniportHaltEx.

Требования

Требование Ценность
минимальные поддерживаемые клиентские Поддерживается в NDIS 6.0 и более поздних версиях.
целевая платформа Всеобщий
заголовка ndis.h (include Ndis.h)
библиотеки Ndis.lib
IRQL PASSIVE_LEVEL

См. также

KeFlushIoBuffers

MiniportHaltEx

MiniportInitializeEx

MiniportSharedMemoryAllocateComplete

NdisAllocateMdl

NdisMAllocateNetBufferSGList

NdisMAllocateSharedMemoryAsyncEx

NdisMFreeSharedMemory

NdisMGetDmaAlignment

NdisMIndicateReceiveNetBufferLists

NdisMSetMiniportAttributes

NdisSystemProcessorCount