Partager via


Fonction MmAllocatePagesForMdlEx (wdm.h)

La routine MmAllocatePagesForMdlEx alloue des pages de mémoire physique non paginées à une MDL.

Utilisez cette routine au lieu de MmAllocatePagesForMdl.

Syntaxe

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

Paramètres

[in] LowAddress

Spécifie l’adresse physique du début de la première plage d’adresses à partir de laquelle les pages allouées peuvent provenir. Si MmAllocatePagesForMdlEx ne peut pas allouer le nombre d’octets demandé dans la première plage d’adresses, il effectue une itération via des plages d’adresses supplémentaires pour obtenir plus de pages. À chaque itération, MmAllocatePagesForMdlEx ajoute la valeur SkipBytes à l’adresse de début précédente pour obtenir le début de la plage d’adresses suivante.

[in] HighAddress

Spécifie l’adresse physique de la fin de la première plage d’adresses à partir de laquelle les pages allouées peuvent provenir.

[in] SkipBytes

Spécifie le nombre d’octets à ignorer au début de la plage d’adresses précédente à partir de laquelle les pages allouées peuvent provenir. SkipBytes doit être un multiple entier de la taille de la page de mémoire virtuelle, en octets.

[in] TotalBytes

Spécifie le nombre total d’octets à allouer pour le MDL.

[in] CacheType

Spécifie une valeur MEMORY_CACHING_TYPE , qui indique le type de mise en cache autorisé pour la mémoire demandée.

[in] Flags

Spécifie les indicateurs pour cette opération. Définissez ce paramètre sur zéro ou sur la valeur OR au niveau du bit d’un ou plusieurs des bits d’indicateur MM_ALLOCATE_XXX suivants :

Les quatre derniers éléments de la liste précédente sont pris en charge uniquement dans Windows 7 et les versions ultérieures de Windows.

Valeur Signification
MM_DONT_ZERO_ALLOCATION 0x00000001 Ne remplissez pas les pages allouées avec des zéros. Par défaut, MmAllocatePagesForMdlEx supprime les pages qu’il alloue. En ignorant cette opération, vous pouvez potentiellement améliorer les performances de l’appel MmAllocatePagesForMdlEx. Toutefois, vous ne devez pas utiliser cet indicateur, sauf si vous n’exposez jamais les pages allouées à des programmes en mode utilisateur ou si vous remplacez toujours le contenu d’origine des pages avant d’exposer les pages allouées à des programmes en mode utilisateur.
MM_ALLOCATE_FROM_LOCAL_NODE_ONLY 0x00000002 Allouez des pages uniquement à partir du nœud idéal. Cet indicateur s’applique uniquement aux systèmes multiprocesseurs qui ont des architectures d’accès à la mémoire non uniforme (NUMA). À compter de Windows Vista, cet indicateur indique que toutes les pages doivent être allouées à partir du nœud idéal du thread actuel. Aucune page ne doit être allouée à partir d’autres nœuds. Dans les versions de Windows antérieures à Windows Vista, cet indicateur indique que toutes les pages doivent être allouées à partir du nœud local ; c’est-à-dire à partir du nœud auquel appartient le processeur actuel. Pour plus d’informations sur les systèmes multiprocesseurs NUMA, consultez Prise en charge de NUMA .
MM_ALLOCATE_FULLY_REQUIRED 0x00000004 Une allocation complète est requise. À compter de Windows 7, cet indicateur exige que MmAllocatePagesForMdlEx retourne NULL s’il ne peut pas allouer toutes les pages demandées. La routine retourne une valeur non NULL uniquement si elle obtient avec succès l’intégralité de l’allocation demandée. Cet indicateur permet au gestionnaire de mémoire d’effectuer l’allocation plus efficacement dans les cas où l’appelant a besoin d’une allocation complète.
MM_ALLOCATE_NO_WAIT 0x00000008 N’attendez pas. À compter de Windows 7, cet indicateur indique que l’appel MmAllocatePagesForMdlEx ne doit pas bloquer le thread appelant. En règle générale, l’appelant est un pilote en mode noyau qui s’exécute au DISPATCH_LEVEL IRQL < , mais ne peut pas autoriser le blocage de son exécution. Par exemple, le pilote peut aider à effectuer des opérations de pagination ou de gestion de l’alimentation. Que cet indicateur soit défini ou non, MmAllocatePagesForMdlEx ne bloque jamais les appelants qui s’exécutent à IRQL = DISPATCH_LEVEL.
0x00000010 MM_ALLOCATE_PREFER_CONTIGUOUS L’allocation est effectuée de manière à réduire la fragmentation de la mémoire système. À compter de Windows 7, cet indicateur indique que l’appelant souhaite éviter de fragmenter la mémoire physique pour rendre la mémoire plus contiguë disponible pour d’autres appelants. Les pages allouées ne sont pas garanties (et ne le sont généralement pas) physiquement contiguës, même si une grande quantité de mémoire contiguë est disponible. Les appelants qui nécessitent une mémoire contiguë doivent spécifier MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS au lieu de MM_ALLOCATE_PREFER_CONTIGUOUS.
0x00000020 MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS La mémoire contiguë est requise. À compter de Windows 7, cet indicateur indique que les pages demandées doivent être allouées en tant que blocs contigus de mémoire physique. Si le paramètre SkipBytes est égal à zéro, MmAllocatePagesForMdlEx réussit et retourne un seul bloc contigu, ou il échoue et retourne NULL. Il ne retourne jamais une allocation partielle. Pour SkipBytes = 0, les pages allouées répondent aux exigences de plage d’adresses spécifiées par les paramètres LowAddress et HighAddress, mais les pages ne sont soumises à aucune restriction d’alignement spéciale. Si SkipBytes est différent de zéro, SkipBytes doit avoir une puissance de deux et doit être supérieure ou égale à PAGE_SIZE, et la valeur du paramètre TotalBytes doit être un multiple de SkipBytes. Dans ce cas, le MDL retourné peut contenir plusieurs blocs de pages contiguës. Autrement dit, chaque bloc est contigu en interne, mais les blocs ne sont pas nécessairement contigus les uns avec les autres. Chaque bloc de pages contiguës est garanti pour être exactement long skipbytes et être aligné sur une limite SkipBytes. Des allocations partielles peuvent se produire si SkipBytes est différent de zéro, mais que chaque bloc contigu dans une allocation partielle est garanti comme long.
MM_ALLOCATE_FAST_LARGE_PAGES 0x00000040 À compter de Windows 8, cet indicateur spécifie que l’allocation doit être satisfaite à partir du cache de grandes pages du système d’exploitation. Si le cache est vide, l’allocation échoue.  Si MM_ALLOCATE_FAST_LARGE_PAGES n’est pas spécifié, MmAllocatePagesForMdlEx utilise des pages volumineuses mises en cache si elles sont disponibles. Si le cache est épuisé, MmAllocatePagesForMdlEx tente de construire des pages volumineuses supplémentaires, ce qui peut prendre beaucoup de temps. MM_ALLOCATE_FAST_LARGE_PAGES doit être utilisé avec l’indicateur MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS. Le paramètre SkipBytes doit être défini sur un multiple de grande taille de page.
MM_ALLOCATE_AND_HOT_REMOVE 0x00000100 À compter de Windows 10, cet indicateur entraîne la suppression des pages allouées du pool de mémoire physique géré par Windows. MM_ALLOCATE_AND_HOT_REMOVE ne peut pas être spécifié avec MM_ALLOCATE_FULLY_REQUIRED. Si MM_ALLOCATE_AND_HOT_REMOVE est spécifié, l’appelant doit s’exécuter à IRQL = PASSIVE_LEVEL.

Valeur retournée

MmAllocatePagesForMdlEx retourne l’un des éléments suivants :

Code de retour Description
Pointeur MDL Une valeur de retour non NULL est un pointeur vers un MDL qui décrit un ensemble de pages physiques dans la plage d’adresses spécifiée. Si le nombre d’octets demandé n’est pas disponible, le MDL décrit la quantité de mémoire physique disponible.
NULL Indique qu’aucune page de mémoire physique n’est disponible dans les plages d’adresses spécifiées ou qu’il n’y a pas suffisamment de pool de mémoires pour le MDL lui-même.

Remarques

Par défaut, les pages de mémoire physique retournées par MmAllocatePagesForMdlEx ne sont pas des pages contiguës. À compter de Windows 7, les appelants peuvent remplacer le comportement par défaut de cette routine en définissant le bit d’indicateur MM_ALLOCATE_PREFER_CONTIGUOUS ou MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS dans le paramètre Flags .

MmAllocatePagesForMdlEx est conçu pour les pilotes en mode noyau qui n’ont pas besoin d’adresses virtuelles correspondantes (c’est-à-dire, ils ont besoin de pages physiques et n’ont pas besoin qu’elles soient contiguës physiquement), et pour les pilotes en mode noyau qui peuvent obtenir des gains de performances substantiels si la mémoire physique d’un appareil est allouée dans une plage d’adresses physique spécifique (par exemple, une carte graphique AGP).

En fonction de la quantité de mémoire physique actuellement disponible dans les plages demandées, MmAllocatePagesForMdlEx peut renvoyer un MDL qui décrit moins de mémoire que ce qui a été demandé. La routine peut également retourner null si aucune mémoire n’a été allouée. L’appelant doit case activée la quantité de mémoire allouée au MDL.

L’appelant doit utiliser MmFreePagesFromMdl pour libérer les pages mémoire décrites par un MDL créé par MmAllocatePagesForMdlEx. Après avoir appelé MmFreePagesFromMdl, l’appelant doit également appeler ExFreePool pour libérer la mémoire allouée pour la structure MDL.

Par défaut, MmAllocatePagesForMdlEx remplit les pages qu’il alloue avec des zéros. L’appelant peut spécifier l’indicateur MM_DONT_ZERO_ALLOCATION pour remplacer cette valeur par défaut et éventuellement améliorer les performances.

La mémoire allouée par MmAllocatePagesForMdlEx n’est pas initialisée si vous spécifiez l’indicateur MM_DONT_ZERO_ALLOCATION. Un pilote en mode noyau doit d’abord zéro cette mémoire si le pilote veut rendre la mémoire visible pour les logiciels en mode utilisateur (afin d’éviter toute fuite de contenu potentiellement privilégié). Pour plus d’informations sur cet indicateur, consultez MM_ALLOCATE_XXX.

La quantité maximale de mémoire que MmAllocatePagesForMdlEx peut allouer en un seul appel est (4 gigaoctets - PAGE_SIZE). La routine ne peut répondre à une demande d’allocation pour ce montant que si suffisamment de pages sont disponibles.

MmAllocatePagesForMdlEx s’exécute à IRQL <= APC_LEVEL. Les appelants de MmAllocatePagesForMdlEx sont autorisés à se trouver à DISPATCH_LEVEL. Toutefois, vous pouvez améliorer les performances du pilote en appelant à APC_LEVEL ou en dessous.

Configuration requise

Condition requise Valeur
Plateforme cible Universal
En-tête wdm.h (inclure Wdm.h, Ntddk.h, Ntifs.h)
Bibliothèque NtosKrnl.lib
DLL NtosKrnl.exe
IRQL Consultez la section Notes.
Règles de conformité DDI IrqlMmApcLte(wdm)

Voir aussi

ExFreePool

MEMORY_CACHING_TYPE

MmAllocatePagesForMdl

MmFreePagesFromMdl

MmMapLockedPages