Función MmAllocatePagesForMdlEx (wdm.h)

La rutina MmAllocatePagesForMdlEx asigna páginas de memoria física no paginadas a un MDL.

Use esta rutina en lugar de MmAllocatePagesForMdl.

Sintaxis

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
);

Parámetros

[in] LowAddress

Especifica la dirección física del inicio del primer intervalo de direcciones desde el que pueden venir las páginas asignadas. Si MmAllocatePagesForMdlEx no puede asignar el número solicitado de bytes en el primer intervalo de direcciones, recorre en iteración intervalos de direcciones adicionales para obtener más páginas. En cada iteración, MmAllocatePagesForMdlEx agrega el valor de SkipBytes a la dirección de inicio anterior para obtener el inicio del siguiente intervalo de direcciones.

[in] HighAddress

Especifica la dirección física del final del primer intervalo de direcciones del que pueden proceder las páginas asignadas.

[in] SkipBytes

Especifica el número de bytes que se van a omitir desde el principio del intervalo de direcciones anterior del que pueden proceder las páginas asignadas. SkipBytes debe ser un entero múltiplo del tamaño de página de memoria virtual, en bytes.

[in] TotalBytes

Especifica el número total de bytes que se van a asignar para mdl.

[in] CacheType

Especifica un valor de MEMORY_CACHING_TYPE , que indica el tipo de almacenamiento en caché permitido para la memoria solicitada.

[in] Flags

Especifica marcas para esta operación. Establezca este parámetro en cero o en el or bit a bit de uno o varios de los siguientes bits de marca MM_ALLOCATE_XXX :

Los cuatro últimos elementos de la lista anterior solo se admiten en Windows 7 y versiones posteriores de Windows.

Valor Significado
MM_DONT_ZERO_ALLOCATION 0x00000001 No rellene las páginas asignadas con ceros. De forma predeterminada, MmAllocatePagesForMdlEx cero las páginas que asigna. Al omitir esta operación, puede mejorar potencialmente el rendimiento de la llamada MmAllocatePagesForMdlEx. Sin embargo, no debe usar esta marca a menos que nunca exponga las páginas asignadas a programas en modo de usuario, o siempre sobrescriba el contenido original de las páginas antes de exponer las páginas asignadas a los programas en modo de usuario.
MM_ALLOCATE_FROM_LOCAL_NODE_ONLY 0x00000002 Asigne páginas solo desde el nodo ideal. Esta marca solo se aplica a los sistemas multiprocesador que tienen arquitecturas de acceso a memoria no uniforme (NUMA). A partir de Windows Vista, esta marca indica que todas las páginas deben asignarse desde el nodo ideal del subproceso actual. No se asignarán páginas desde otros nodos. En versiones de Windows anteriores a Windows Vista, esta marca indica que todas las páginas deben asignarse desde el nodo local; es decir, del nodo al que pertenece el procesador actual. Para obtener más información sobre los sistemas multiprocesador NUMA, vea Compatibilidad con NUMA .
MM_ALLOCATE_FULLY_REQUIRED 0x00000004 Se requiere una asignación completa. A partir de Windows 7, esta marca requiere MmAllocatePagesForMdlEx para devolver NULL si no puede asignar todas las páginas solicitadas. La rutina devuelve un valor distinto de NULL solo si obtiene correctamente toda la asignación solicitada. Esta marca permite al administrador de memoria realizar la asignación de forma más eficaz en los casos en los que el autor de la llamada requiere una asignación completa.
MM_ALLOCATE_NO_WAIT 0x00000008 No esperes. A partir de Windows 7, esta marca indica que la llamada MmAllocatePagesForMdlEx no debe bloquear el subproceso que realiza la llamada. Normalmente, el autor de la llamada es un controlador en modo kernel que se ejecuta en IRQL < DISPATCH_LEVEL pero no puede permitir que se bloquee su ejecución. Por ejemplo, el controlador podría ayudar con las operaciones de paginación o administración de energía. Independientemente de si se establece esta marca, MmAllocatePagesForMdlEx nunca bloquea a los autores de llamadas que se ejecutan en IRQL = DISPATCH_LEVEL.
MM_ALLOCATE_PREFER_CONTIGUOUS 0x00000010 La asignación se realiza de forma que minimice la fragmentación de memoria del sistema. A partir de Windows 7, esta marca indica que el autor de la llamada quiere evitar fragmentar la memoria física para que la memoria más contigua esté disponible para otros autores de llamadas. No se garantiza que las páginas asignadas sean (y normalmente no son) físicamente contiguas, incluso si hay mucha memoria contigua disponible. Los autores de llamadas que requieren memoria contigua deben especificar MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS en lugar de MM_ALLOCATE_PREFER_CONTIGUOUS.
MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS 0x00000020 Se requiere memoria contigua. A partir de Windows 7, esta marca indica que las páginas solicitadas deben asignarse como bloques contiguos de memoria física. Si el parámetro SkipBytes es cero, MmAllocatePagesForMdlEx se realiza correctamente y devuelve un único bloque contiguo o produce un error y devuelve NULL. Nunca devuelve una asignación parcial. Para SkipBytes = 0, las páginas asignadas cumplen los requisitos de intervalo de direcciones especificados por los parámetros LowAddress y HighAddress, pero las páginas están sujetas a restricciones de alineación especiales. Si SkipBytes es distinto de cero, SkipBytes debe ser una potencia de dos y debe ser mayor o igual que PAGE_SIZE, y el valor del parámetro TotalBytes debe ser un múltiplo de SkipBytes. En este caso, el MDL devuelto puede contener varios bloques de páginas contiguas. Es decir, cada bloque es internamente contiguo, pero los bloques no son necesariamente contiguos entre sí. Se garantiza que cada bloque de páginas contiguas sea exactamente long SkipBytes y que se alinee en un límite SkipBytes. Las asignaciones parciales pueden producirse si SkipBytes es distinto de cero, pero se garantiza que cada bloque contiguo de una asignación parcial sea SkipBytes long.
MM_ALLOCATE_FAST_LARGE_PAGES 0x00000040 A partir de Windows 8, esta marca especifica que la asignación debe cumplirse desde la caché de páginas grandes del sistema operativo. Si la memoria caché está vacía, se produce un error en la asignación.  Si no se especifica MM_ALLOCATE_FAST_LARGE_PAGES, MmAllocatePagesForMdlEx usa páginas grandes almacenadas en caché si están disponibles. Si se agota la memoria caché, MmAllocatePagesForMdlEx intenta construir páginas grandes adicionales, lo que puede tardar mucho tiempo. MM_ALLOCATE_FAST_LARGE_PAGES debe usarse con la marca MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS. El parámetro SkipBytes debe establecerse en un múltiplo de tamaño de página grande.
MM_ALLOCATE_AND_HOT_REMOVE 0x00000100 A partir de Windows 10, esta marca hace que las páginas asignadas se quiten del grupo de memoria física administrada por Windows. MM_ALLOCATE_AND_HOT_REMOVE no se puede especificar junto con MM_ALLOCATE_FULLY_REQUIRED. Si se especifica MM_ALLOCATE_AND_HOT_REMOVE, el autor de la llamada debe ejecutarse en IRQL = PASSIVE_LEVEL.

Valor devuelto

MmAllocatePagesForMdlEx devuelve una de las siguientes opciones:

Código devuelto Descripción
Puntero MDL Un valor devuelto distinto de NULL es un puntero a un MDL que describe un conjunto de páginas físicas en el intervalo de direcciones especificado. Si el número solicitado de bytes no está disponible, MDL describe tanta memoria física como está disponible.
NULL Indica que no hay páginas de memoria física disponibles en los intervalos de direcciones especificados o que no hay suficiente grupo de memoria para la propia MDL.

Comentarios

De forma predeterminada, las páginas de memoria física que devuelve MmAllocatePagesForMdlEx no son páginas contiguas. A partir de Windows 7, los llamadores pueden invalidar el comportamiento predeterminado de esta rutina estableciendo el bit de marca MM_ALLOCATE_PREFER_CONTIGUOUS o MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS en el parámetro Flags .

MmAllocatePagesForMdlEx está diseñado para controladores en modo kernel que no necesitan direcciones virtuales correspondientes (es decir, necesitan páginas físicas y no necesitan que sean físicamente contiguas) y para controladores en modo kernel que pueden lograr mejoras sustanciales de rendimiento si se asigna memoria física para un dispositivo en un intervalo de direcciones físicas específico (por ejemplo, una tarjeta gráfica AGP).

Dependiendo de la cantidad de memoria física disponible actualmente en los intervalos solicitados, MmAllocatePagesForMdlEx podría devolver una MDL que describa menos memoria de la solicitada. La rutina también podría devolver NULL si no se asignó ninguna memoria. El autor de la llamada debe comprobar la cantidad de memoria que se asigna realmente al MDL.

El llamador debe usar MmFreePagesFromMdl para liberar las páginas de memoria descritas por un MDL creado por MmAllocatePagesForMdlEx. Después de llamar a MmFreePagesFromMdl, el autor de la llamada también debe llamar a ExFreePool para liberar la memoria asignada para la estructura MDL.

De forma predeterminada, MmAllocatePagesForMdlEx rellena las páginas que asigna con ceros. El autor de la llamada puede especificar la marca MM_DONT_ZERO_ALLOCATION para invalidar este valor predeterminado y, posiblemente, mejorar el rendimiento.

La memoria que mmAllocatePagesForMdlEx asigna no está inicializada si especifica la marca MM_DONT_ZERO_ALLOCATION. Un controlador en modo kernel primero debe cero esta memoria si el controlador va a hacer que la memoria sea visible para el software en modo de usuario (para evitar la pérdida de contenido potencialmente con privilegios). Para obtener más información sobre esta marca, vea MM_ALLOCATE_XXX.

La cantidad máxima de memoria que MmAllocatePagesForMdlEx puede asignar en una sola llamada es (4 gigabytes - PAGE_SIZE). La rutina puede satisfacer una solicitud de asignación para esta cantidad solo si hay suficientes páginas disponibles.

MmAllocatePagesForMdlEx se ejecuta en IRQL <= APC_LEVEL. Los autores de llamadas de MmAllocatePagesForMdlEx pueden estar en DISPATCH_LEVEL. Sin embargo, puede mejorar el rendimiento del controlador llamando a APC_LEVEL o a continuación.

Requisitos

Requisito Value
Plataforma de destino Universal
Encabezado wdm.h (incluya Wdm.h, Ntddk.h, Ntifs.h)
Library NtosKrnl.lib
Archivo DLL NtosKrnl.exe
IRQL vea la sección Comentarios.
Reglas de cumplimiento de DDI IrqlMmApcLte(wdm)

Consulte también

ExFreePool

MEMORY_CACHING_TYPE

MmAllocatePagesForMdl

MmFreePagesFromMdl

MmMapLockedPages