Partager via


MmAllocatePagesForMdlEx, fonction (wdm.h)

La routine MmAllocatePagesForMdlEx alloue des pages de mémoire physique non paginées à un 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 venir. Si MmAllocatePagesForMdlEx ne peut pas allouer le nombre demandé d’octets dans la première plage d’adresses, il itère via des plages d’adresses supplémentaires pour obtenir plus de pages. À chaque itération, MmAllocatePagesForMdlEx ajoute la valeur de 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 à partir du 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 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ée pour la mémoire demandée.

[in] Flags

Spécifie des indicateurs pour cette opération. Définissez ce paramètre sur zéro ou sur l’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 zéro 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 aux programmes en mode utilisateur, ou si vous remplacez toujours le contenu d’origine des pages avant d’exposer les pages allouées aux 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 ; autrement dit, 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 correctement l’allocation demandée. Cet indicateur permet au gestionnaire de mémoire d’effectuer l’allocation plus efficacement dans les cas où l’appelant requiert 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 à l'< DISPATCH_LEVEL IRQL, mais ne peut pas autoriser son exécution à être bloquée. Par exemple, le pilote peut aider à paginer ou à gérer l’alimentation. Que cet indicateur soit défini, MmAllocatePagesForMdlEx ne bloque jamais les appelants qui s’exécutent à IRQL = DISPATCH_LEVEL.
MM_ALLOCATE_PREFER_CONTIGUOUS 0x00000010 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 d’être (et généralement ne sont pas) contiguës physiquement, même si beaucoup 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.
MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS 0x00000020 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 bloc contigu unique, 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 particulière. Si SkipBytes n’est pas différent de zéro, SkipBytes doit être une puissance de deux et doit être supérieure ou égale à PAGE_SIZE, et la valeur du paramètre TotalBytes doit être un multiple d’octets 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 SkipBytes long et être aligné sur une limite SkipBytes. Les allocations partielles peuvent se produire si SkipBytes n’est pas différent de zéro, mais chaque bloc contigu dans une allocation partielle est garanti pour être Long SkipBytes.
MM_ALLOCATE_FAST_LARGE_PAGES 0x00000040 À compter de Windows 8, cet indicateur spécifie que l’allocation doit être satisfaite à partir du cache de pages volumineux 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 devez être utilisé avec l’indicateur de 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ée 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 de retour

MmAllocatePagesForMdlEx retourne l’une des valeurs suivantes :

Retourner le code Description
pointeur MDL Une valeur de retourNULL non 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 demandé d’octets n’est pas disponible, le MDL décrit autant de mémoire physique que 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émoire pour le MDL lui-même.

Remarques

Par défaut, les pages de mémoire physique qui MmAllocatePagesForMdlEx retournent 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 Indicateurs.

MmAllocatePagesForMdlEx est conçu pour les pilotes en mode noyau qui n’ont pas besoin d’adresses virtuelles correspondantes (autrement dit, 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 considérables 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).

Selon la quantité de mémoire physique actuellement disponible dans les plages demandées, MmAllocatePagesForMdlEx peut retourner 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 vérifier 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 zéros. L’appelant peut spécifier l’indicateur de MM_DONT_ZERO_ALLOCATION pour remplacer cette valeur par défaut et améliorer éventuellement les performances.

La mémoire qui MmAllocatePagesForMdlEx alloue est non initialisée si vous spécifiez l’indicateur de MM_DONT_ZERO_ALLOCATION. Un pilote en mode noyau doit d’abord zéro cette mémoire si le pilote va rendre la mémoire visible par les logiciels en mode utilisateur (pour éviter la 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 dans un seul appel est (4 gigaoctets - PAGE_SIZE). La routine peut satisfaire une demande d’allocation pour ce montant uniquement si suffisamment de pages sont disponibles.

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

Exigences

Exigence Valeur
plateforme cible Universel
d’en-tête wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
bibliothèque NtosKrnl.lib
DLL NtosKrnl.exe
IRQL Voir la section Remarques.
règles de conformité DDI IrqlMmApcLte(wdm)

Voir aussi

ExFreePool

MEMORY_CACHING_TYPE

MmAllocatePagesForMdl

MmFreePagesFromMdl

mmMapLockedPages