Функция 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.
Возвращаемое значение
Никакой
Замечания
NdisMAllocateSharedMemory предоставляет как сопоставленный диапазон виртуальных адресов, используемый драйвером для доступа к блоку общей памяти, так и диапазону типа NDIS_PHYSICAL_ADDRESS, используемому сетевой картой. Значение, возвращаемое в PhysicalAddress, может быть вдвойне сопоставлено системой. То есть диапазон "физических" адресов, описанный значением PhysicalAddress и Length может быть диапазоном сопоставленных логических адресов, которые не соответствуют физическим адресам узла для выделения на каждой возможной платформе.
NdisMAllocateSharedMemory можно вызывать только из MiniportInitializeEx. Насколько большое выделение для запроса зависит от того, как модуль записи драйверов, зная возможности и функции сетевого адаптера, решает сделать компромисс между следующей производительностью и дилеммой размера:
-
В периоды высокого сетевого трафика минипорт-драйвер не может поддерживать высокую пропускную способность ввода-вывода, если он работает с низким объемом общего пространства памяти для буферов данных, доступных для устройств.
Например, минипорт-драйвер может указывать, что буферы получения в общей памяти быстрее, чем такие буферы возвращаются из драйверов привязанного протокола при наводнении получения сетевых адаптеров. Если все его общее пространство памяти потребляется выдающимися буферами получения, драйвер минипорта может отключить прерывания приема на сетевом адаптере, пока не будет доступно некоторое общее пространство памяти для буферов получения.
- С другой стороны, вызов NdisMAllocateSharedMemory с Length, выбранным для прогнозирования некоторого максимального спроса на передачу, делает изображение драйвера более большим и его использование ресурсов довольно неэкономично, за исключением редких периодов очень высокого спроса ввода-вывода. Кроме того, NdisMAllocateSharedMemory может не дать драйверу такой большой блок, если недостаточно системной памяти, принудив драйверу завершить инициализацию.
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 |