Функция MmAllocatePagesForMdlEx (wdm.h)

Подпрограмма MmAllocatePagesForMdlEx выделяет невыгремые страницы физической памяти для MDL.

Используйте эту подпрограмму вместо MmAllocatePagesForMdl.

Синтаксис

PMDL MmAllocatePagesForMdlEx(
  [in] PHYSICAL_ADDRESS    LowAddress,
  [in] PHYSICAL_ADDRESS    HighAddress,
  [in] PHYSICAL_ADDRESS    SkipBytes,
  [in] SIZE_T              TotalBytes,
  [in] MEMORY_CACHING_TYPE CacheType,
  [in] ULONG               Flags
);

Параметры

[in] LowAddress

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

[in] HighAddress

Указывает физический адрес конца первого диапазона адресов, из который могут поступать выделенные страницы.

[in] SkipBytes

Указывает количество байтов, которые необходимо пропустить с начала предыдущего диапазона адресов, из которых могут поступать выделенные страницы. SkipBytes должен быть целым числом, кратным размеру страницы виртуальной памяти, в байтах.

[in] TotalBytes

Указывает общее количество байтов, выделяемых для MDL.

[in] CacheType

Задает значение MEMORY_CACHING_TYPE , указывающее тип кэширования, разрешенного для запрошенной памяти.

[in] Flags

Задает флаги для этой операции. Присвойте этому параметру значение ноль или побитовое ЗНАЧЕНИЕ ИЛИ одного или нескольких из следующих битов флага MM_ALLOCATE_XXX :

Последние четыре элемента в предыдущем списке поддерживаются только в Windows 7 и более поздних версиях Windows.

Значение Значение
0x00000001 MM_DONT_ZERO_ALLOCATION Не заполняйте выделенные страницы нулями. По умолчанию MmAllocatePagesForMdlEx обнуляет выделенные страницы. Пропустив эту операцию, можно повысить производительность вызова MmAllocatePagesForMdlEx. Однако этот флаг не следует использовать, если вы никогда не предоставляете выделенные страницы программам пользовательского режима или всегда перезаписываете исходное содержимое страниц, прежде чем предоставлять выделенные страницы программам пользовательского режима.
MM_ALLOCATE_FROM_LOCAL_NODE_ONLY 0x00000002 Выделение страниц только из идеального узла. Этот флаг применяется только к многопроцессорным системам с архитектурами неоднородного доступа к памяти (NUMA). Начиная с Windows Vista, этот флаг указывает, что все страницы должны быть выделены из идеального узла текущего потока. Никакие страницы не должны быть выделены из других узлов. В версиях Windows, предшествующих Windows Vista, этот флаг указывает, что все страницы должны быть выделены из локального узла; то есть из узла, к которому принадлежит текущий процессор. Дополнительные сведения о многопроцессорных системах NUMA см. в разделе Поддержка NUMA .
MM_ALLOCATE_FULLY_REQUIRED 0x00000004 Требуется полное выделение ресурсов. Начиная с Windows 7, этот флаг требует, чтобы MmAllocatePagesForMdlEx возвращал значение NULL, если он не может выделить все запрошенные страницы. Подпрограмма возвращает значение, отличное от NULL, только если она успешно получает все запрошенное выделение. Этот флаг позволяет диспетчеру памяти более эффективно выполнять выделение в случаях, когда вызывающей объекту требуется полное выделение.
MM_ALLOCATE_NO_WAIT 0x00000008 Не ждите. Начиная с Windows 7, этот флаг указывает, что вызов MmAllocatePagesForMdlEx не должен блокировать вызывающий поток. Как правило, вызывающий объект является драйвером в режиме ядра, который работает в IRQL < DISPATCH_LEVEL но не может допустить блокировки его выполнения. Например, драйвер может помочь с разбиением по страницам или операциями управления питанием. Независимо от того, установлен ли этот флаг, MmAllocatePagesForMdlEx никогда не блокирует вызывающие объекты, работающие в IRQL = DISPATCH_LEVEL.
0x00000010 MM_ALLOCATE_PREFER_CONTIGUOUS Выделение выполняется таким образом, чтобы свести к минимуму фрагментацию системной памяти. Начиная с Windows 7, этот флаг указывает, что вызывающий объект хочет избежать фрагментирования физической памяти, чтобы сделать более непрерывную память доступной для других вызывающих. Выделенные страницы не гарантированы (и обычно не являются) физически смежными, даже если доступно много непрерывной памяти. Вызывающие абоненты, которым требуется непрерывная память, должны указывать MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS, а не MM_ALLOCATE_PREFER_CONTIGUOUS.
0x00000020 MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS Требуется непрерывная память. Начиная с Windows 7, этот флаг указывает, что запрошенные страницы должны быть выделены как непрерывные блоки физической памяти. Если параметр SkipBytes равен нулю, mmAllocatePagesForMdlEx либо завершается успешно и возвращает один непрерывный блок, либо завершается сбоем и возвращает значение NULL. Он никогда не возвращает частичное выделение. Для SkipBytes = 0 выделенные страницы соответствуют требованиям к диапазону адресов, заданным параметрами LowAddress и HighAddress, но на страницы не распространяются специальные ограничения выравнивания. Если Значение SkipBytes не равно нулю, значение SkipBytes должно быть равно двум и должно быть больше или равно PAGE_SIZE, а значение параметра TotalBytes должно быть кратно SkipBytes. В этом случае возвращаемый MDL может содержать несколько блоков смежных страниц. То есть каждый блок является внутренне смежным, но блоки не обязательно связаны друг с другом. Каждый блок смежных страниц гарантированно имеет длину SkipBytes и выравнивается по границе SkipBytes. Частичное выделение может произойти, если SkipBytes не является нулевым, но каждый смежный блок в частичном выделении гарантированно будет длиной SkipBytes.
MM_ALLOCATE_FAST_LARGE_PAGES 0x00000040 Начиная с Windows 8, этот флаг указывает, что выделение должно быть удовлетворено из большого кэша страниц операционной системы. Если кэш пуст, выделение завершается ошибкой.  Если MM_ALLOCATE_FAST_LARGE_PAGES не указан, MmAllocatePagesForMdlEx использует кэшированные большие страницы, если они доступны. Если кэш исчерпан, MmAllocatePagesForMdlEx пытается создать дополнительные большие страницы, что может занять много времени. MM_ALLOCATE_FAST_LARGE_PAGES необходимо использовать с флагом MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS. Параметр SkipBytes должен иметь значение, кратное большому размеру страницы.
0x00000100 MM_ALLOCATE_AND_HOT_REMOVE Начиная с Windows 10, этот флаг приводит к удалению выделенных страниц из пула физической памяти, управляемого Windows. MM_ALLOCATE_AND_HOT_REMOVE нельзя указать вместе с MM_ALLOCATE_FULLY_REQUIRED. Если указан MM_ALLOCATE_AND_HOT_REMOVE, вызывающий объект должен выполняться в IRQL = PASSIVE_LEVEL.

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

MmAllocatePagesForMdlEx возвращает одно из следующих результатов:

Код возврата Описание
Указатель MDL Возвращаемое значение, отличное от NULL , — это указатель на MDL, описывающий набор физических страниц в указанном диапазоне адресов. Если запрошено количество байтов недоступно, MDL описывает столько физической памяти, сколько доступно.
NULL Указывает, что в указанных диапазонах адресов отсутствуют страницы физической памяти или что пула памяти недостаточно для самого MDL.

Комментарии

По умолчанию страницы физической памяти, возвращаемые MmAllocatePagesForMdlEx , не являются смежными страницами. Начиная с Windows 7 вызывающие абоненты могут переопределить поведение этой подпрограммы по умолчанию, задав бит флага MM_ALLOCATE_PREFER_CONTIGUOUS или MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS в параметре Flags .

MmAllocatePagesForMdlEx предназначен для драйверов в режиме ядра, которым не требуются соответствующие виртуальные адреса (т. е. им нужны физические страницы и не должны быть физически смежными), а также для драйверов режима ядра, которые могут значительно повысить производительность, если физическая память устройства выделяется в определенном диапазоне физических адресов (например, графики AGP карта).

В зависимости от того, какой объем физической памяти в настоящее время доступен в запрошенных диапазонах, MmAllocatePagesForMdlEx может возвращать MDL, описывающий меньше памяти, чем было запрошено. Подпрограмма также может возвращать значение NULL , если память не выделена. Вызывающий объект должен проверка объем памяти, фактически выделенный для MDL.

Вызывающий объект должен использовать MmFreePagesFromMdl , чтобы освободить страницы памяти, описанные в MDL, созданном MmAllocatePagesForMdlEx. После вызова MmFreePagesFromMdl вызывающий объект также должен вызвать ExFreePool , чтобы освободить память, выделенную для структуры MDL.

По умолчанию MmAllocatePagesForMdlEx заполняет выделенные страницы нулями. Вызывающий объект может указать флаг MM_DONT_ZERO_ALLOCATION, чтобы переопределить это значение по умолчанию и, возможно, повысить производительность.

Память, выделенная MmAllocatePagesForMdlEx , не инициализируется, если указать флаг MM_DONT_ZERO_ALLOCATION. Драйвер режима ядра должен сначала обнулить эту память, если драйвер собирается сделать память видимой для программного обеспечения пользовательского режима (чтобы избежать утечки потенциально привилегированного содержимого). Дополнительные сведения об этом флаге см. в разделе MM_ALLOCATE_XXX.

Максимальный объем памяти, который mmAllocatePagesForMdlEx может выделить в одном вызове, составляет (4 гигабайта — PAGE_SIZE). Подпрограмма может удовлетворить запрос на выделение для этой суммы, только если доступно достаточно страниц.

MmAllocatePagesForMdlEx выполняется в IRQL <= APC_LEVEL. Вызывающие mmAllocatePagesForMdlEx могут находиться на DISPATCH_LEVEL. Тем не менее вы можете повысить производительность драйвера, вызвав APC_LEVEL или ниже.

Требования

Требование Значение
Целевая платформа Универсальное
Верхняя часть wdm.h (включая Wdm.h, Ntddk.h, Ntifs.h)
Библиотека NtosKrnl.lib
DLL NtosKrnl.exe
IRQL См. раздел "Примечания".
Правила соответствия DDI IrqlMmApcLte(wdm)

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

ExFreePool

MEMORY_CACHING_TYPE

MmAllocatePagesForMdl

MmFreePagesFromMdl

MmMapLockedPages