Função MmAllocatePagesForMdlEx (wdm.h)

A rotina MmAllocatePagesForMdlEx aloca páginas de memória física nãopagadas para um MDL.

Use essa rotina em vez de MmAllocatePagesForMdl.

Sintaxe

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 o endereço físico do início do primeiro intervalo de endereços do qual as páginas alocadas podem vir. Se MmAllocatePagesForMdlEx não puder alocar o número solicitado de bytes no primeiro intervalo de endereços, ele itera por meio de intervalos de endereços adicionais para obter mais páginas. Em cada iteração, MmAllocatePagesForMdlEx adiciona o valor de SkipBytes ao endereço inicial anterior para obter o início do próximo intervalo de endereços.

[in] HighAddress

Especifica o endereço físico do final do primeiro intervalo de endereços do qual as páginas alocadas podem vir.

[in] SkipBytes

Especifica o número de bytes a serem ignorados do início do intervalo de endereços anterior do qual as páginas alocadas podem vir. SkipBytes deve ser um múltiplo inteiro do tamanho da página de memória virtual, em bytes.

[in] TotalBytes

Especifica o número total de bytes a serem alocados para o MDL.

[in] CacheType

Especifica um valor MEMORY_CACHING_TYPE , que indica o tipo de cache permitido para a memória solicitada.

[in] Flags

Especifica sinalizadores para esta operação. Defina esse parâmetro como zero ou como OR bit a bit de um ou mais dos seguintes bits de sinalizador MM_ALLOCATE_XXX :

Os últimos quatro itens na lista anterior têm suporte apenas no Windows 7 e versões posteriores do Windows.

Valor Significado
MM_DONT_ZERO_ALLOCATION 0x00000001 Não preencha as páginas alocadas com zeros. Por padrão, MmAllocatePagesForMdlEx zerá as páginas alocadas. Ignorando essa operação, você pode potencialmente melhorar o desempenho da chamada MmAllocatePagesForMdlEx. No entanto, você não deve usar esse sinalizador a menos que nunca exponha as páginas alocadas a programas de modo de usuário ou sempre substitua o conteúdo original das páginas antes de expor as páginas alocadas a programas de modo de usuário.
MM_ALLOCATE_FROM_LOCAL_NODE_ONLY 0x00000002 Aloque páginas somente do nó ideal. Esse sinalizador se aplica somente a sistemas multiprocessadores que têm arquiteturas NUMA (acesso não uniforme à memória). A partir do Windows Vista, esse sinalizador indica que todas as páginas devem ser alocadas do nó ideal do thread atual. Nenhuma página deve ser alocada de outros nós. Em versões do Windows anteriores ao Windows Vista, esse sinalizador indica que todas as páginas devem ser alocadas do nó local; ou seja, do nó ao qual o processador atual pertence. Para obter mais informações sobre sistemas multiprocessadores NUMA, consulte Suporte a NUMA .
MM_ALLOCATE_FULLY_REQUIRED 0x00000004 Uma alocação completa é necessária. A partir do Windows 7, esse sinalizador exige que MmAllocatePagesForMdlEx retorne NULL se não puder alocar todas as páginas solicitadas. A rotina retornará um valor não NULL somente se obtiver com êxito toda a alocação solicitada. Esse sinalizador permite que o gerenciador de memória execute a alocação com mais eficiência nos casos em que o chamador requer uma alocação completa.
MM_ALLOCATE_NO_WAIT 0x00000008 Não espere. A partir do Windows 7, esse sinalizador indica que a chamada MmAllocatePagesForMdlEx não deve bloquear o thread de chamada. Normalmente, o chamador é um driver no modo kernel que está em execução no IRQL < DISPATCH_LEVEL mas não pode permitir que sua execução seja bloqueada. Por exemplo, o driver pode estar auxiliando com operações de paginação ou gerenciamento de energia. Independentemente de esse sinalizador estar definido, MmAllocatePagesForMdlEx nunca bloqueia chamadores que estão em execução em IRQL = DISPATCH_LEVEL.
MM_ALLOCATE_PREFER_CONTIGUOUS 0x00000010 A alocação é executada de forma a minimizar a fragmentação de memória do sistema. A partir do Windows 7, esse sinalizador indica que o chamador deseja evitar fragmentar a memória física para disponibilizar mais memória contígua para outros chamadores. Não há garantia de que as páginas alocadas sejam (e geralmente não são) fisicamente contíguas, mesmo que haja muita memória contígua disponível. Os chamadores que exigem memória contígua devem especificar MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS em vez de MM_ALLOCATE_PREFER_CONTIGUOUS.
MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS 0x00000020 A memória contígua é necessária. A partir do Windows 7, esse sinalizador indica que as páginas solicitadas devem ser alocadas como blocos contíguos de memória física. Se o parâmetro SkipBytes for zero, MmAllocatePagesForMdlEx terá êxito e retornará um único bloco contíguo ou falhará e retornará NULL. Ele nunca retorna uma alocação parcial. Para SkipBytes = 0, as páginas alocadas atendem aos requisitos de intervalo de endereços especificados pelos parâmetros LowAddress e HighAddress, mas as páginas estão sujeitas a nenhuma restrição de alinhamento especial. Se SkipBytes for diferente de zero, SkipBytes deverá ser uma potência de dois e deve ser maior ou igual a PAGE_SIZE e o valor do parâmetro TotalBytes deve ser um múltiplo de SkipBytes. Nesse caso, o MDL retornado pode conter vários blocos de páginas contíguas. Ou seja, cada bloco é internamente contíguo, mas os blocos não são necessariamente contíguos uns com os outros. Cada bloco de páginas contíguas tem a garantia de ser exatamente SkipBytes longo e ser alinhado em um limite SkipBytes. Alocações parciais podem ocorrer se SkipBytes for diferente de zero, mas cada bloco contíguo em uma alocação parcial tem a garantia de ter SkipBytes longo.
MM_ALLOCATE_FAST_LARGE_PAGES 0x00000040 Começando com Windows 8, esse sinalizador especifica que a alocação deve ser atendida do cache de página grande do sistema operacional. Se o cache estiver vazio, a alocação falhará.  Se MM_ALLOCATE_FAST_LARGE_PAGES não for especificado, MmAllocatePagesForMdlEx usará páginas grandes armazenadas em cache se estiverem disponíveis. Se o cache estiver esgotado, MmAllocatePagesForMdlEx tentará construir páginas grandes adicionais, o que pode levar muito tempo. MM_ALLOCATE_FAST_LARGE_PAGES deve ser usado com o sinalizador MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS. O parâmetro SkipBytes deve ser definido como um múltiplo de tamanho de página grande.
0x00000100 MM_ALLOCATE_AND_HOT_REMOVE Começando com Windows 10, esse sinalizador faz com que as páginas alocadas sejam removidas do pool de memória física gerenciado pelo Windows. MM_ALLOCATE_AND_HOT_REMOVE não pode ser especificado junto com MM_ALLOCATE_FULLY_REQUIRED. Se MM_ALLOCATE_AND_HOT_REMOVE for especificado, o chamador deverá estar em execução em IRQL = PASSIVE_LEVEL.

Retornar valor

MmAllocatePagesForMdlEx retorna um dos seguintes:

Código de retorno Descrição
Ponteiro MDL Um valor retornado não NULL é um ponteiro para um MDL que descreve um conjunto de páginas físicas no intervalo de endereços especificado. Se o número solicitado de bytes não estiver disponível, o MDL descreverá a quantidade de memória física disponível.
NULL Indica que nenhuma página de memória física está disponível nos intervalos de endereços especificados ou que não há pool de memória suficiente para o próprio MDL.

Comentários

Por padrão, as páginas de memória física que MmAllocatePagesForMdlEx retorna não são páginas contíguas. A partir do Windows 7, os chamadores podem substituir o comportamento padrão dessa rotina definindo o MM_ALLOCATE_PREFER_CONTIGUOUS ou MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS bit de sinalizador no parâmetro Flags .

MmAllocatePagesForMdlEx foi projetado para drivers de modo kernel que não precisam de endereços virtuais correspondentes (ou seja, eles precisam de páginas físicas e não precisam que sejam fisicamente contíguos) e para drivers no modo kernel que podem obter ganhos substanciais de desempenho se a memória física de um dispositivo for alocada em um intervalo de endereços físico específico (por exemplo, um cartão gráficos AGP).

Dependendo da quantidade de memória física disponível atualmente nos intervalos solicitados, MmAllocatePagesForMdlEx pode retornar um MDL que descreve menos memória do que o solicitado. A rotina também poderá retornar NULL se nenhuma memória tiver sido alocada. O chamador deve marcar a quantidade de memória realmente alocada para o MDL.

O chamador deve usar MmFreePagesFromMdl para liberar as páginas de memória descritas por um MDL que foi criado por MmAllocatePagesForMdlEx. Depois de chamar MmFreePagesFromMdl, o chamador também deve chamar ExFreePool para liberar a memória alocada para a estrutura MDL.

Por padrão, MmAllocatePagesForMdlEx preenche as páginas alocadas com zeros. O chamador pode especificar o sinalizador MM_DONT_ZERO_ALLOCATION para substituir esse padrão e possivelmente melhorar o desempenho.

A memória alocada por MmAllocatePagesForMdlEx não será inicializada se você especificar o sinalizador MM_DONT_ZERO_ALLOCATION. Um driver de modo kernel deve primeiro zero essa memória se o driver for tornar a memória visível para o software no modo de usuário (para evitar vazamento de conteúdo potencialmente privilegiado). Para obter mais informações sobre esse sinalizador, consulte MM_ALLOCATE_XXX.

A quantidade máxima de memória que MmAllocatePagesForMdlEx pode alocar em uma única chamada é (4 gigabytes – PAGE_SIZE). A rotina pode atender a uma solicitação de alocação para esse valor somente se páginas suficientes estiverem disponíveis.

MmAllocatePagesForMdlEx é executado em IRQL <= APC_LEVEL. Os chamadores de MmAllocatePagesForMdlEx têm permissão para estar em DISPATCH_LEVEL. No entanto, você pode melhorar o desempenho do driver chamando em APC_LEVEL ou abaixo.

Requisitos

Requisito Valor
Plataforma de Destino Universal
Cabeçalho wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
Biblioteca NtosKrnl.lib
DLL NtosKrnl.exe
IRQL Consulte a seção Observações.
Regras de conformidade de DDI IrqlMmApcLte(wdm)

Confira também

ExFreePool

MEMORY_CACHING_TYPE

MmAllocatePagesForMdl

MmFreePagesFromMdl

MmMapLockedPages