Partilhar via


Alocação de memória do Espaço do Sistema

Importante

As DDIs ExAllocatePool discutidas neste tópico foram preteridas no Windows 10, versão 2004 e substituídas por ExAllocatePool2 e ExAllocatePool3. Para obter mais informações, consulte Atualização de chamadas ExAllocatePool obsoletas para ExAllocatePool2 e ExAllocatePool3.

Os drivers podem usar o espaço alocado pelo sistema dentro de suas extensões de dispositivo como áreas de armazenamento global para informações específicas do dispositivo. Os drivers podem usar apenas a pilha do kernel para passar pequenas quantidades de dados para as suas rotinas internas. Alguns drivers têm que alocar quantidades adicionais e maiores de memória de espaço do sistema, normalmente para buffers de E/S.

Para alocar espaço de buffer de E/S, as melhores rotinas de alocação de memória a serem usadas são MmAllocateNonCachedMemory, MmAllocateContiguousMemorySpecifyCache, AllocateCommonBuffer (se o dispositivo do driver usar o DMA bus-master ou o modo de inicialização automática de um controlador DMA do sistema) ou ExAllocatePoolWithTag.

O pool não paginado normalmente fica fragmentado à medida que o sistema é executado, portanto, a rotina DriverEntry de um driver deve chamar essas rotinas para configurar qualquer buffer de E/S de longo prazo de que o driver precisa. Cada uma dessas rotinas, exceto ExAllocatePoolWithTag, aloca memória alinhada em um limite específico do processador (determinado pelo tamanho da linha de cache de dados do processador) para fornecer o melhor desempenho.

Os drivers devem alocar buffers de E/S da forma mais econômica possível, porque a memória de pool não paginada é um recurso limitado do sistema. Normalmente, um driver deve evitar chamar essas rotinas de suporte repetidamente para solicitar alocações de menos de PAGE_SIZE porque cada alocação menor que PAGE_SIZE também vem com um cabeçalho de pool que é usado para gerenciar internamente a alocação.

Dicas para alocar espaço de buffer de driver economicamente

Para alocar memória buffer de E/S de forma econômica, esteja ciente do seguinte:

  • Cada chamada para MmAllocateNonCachedMemory ou MmAllocateContiguousMemorySpecifyCache sempre retorna um múltiplo completo do tamanho da página do sistema, de memória de espaço do sistema não paginada, independentemente do tamanho da alocação solicitada. Portanto, as solicitações de menos de uma página são arredondadas para uma página inteira, e quaisquer bytes restantes na página são desperdiçados; estes são inacessíveis pelo driver que chamou a função e não podem ser utilizados por outro código em modo kernel.

  • Cada chamada para AllocateCommonBuffer usa pelo menos um registro de mapa de objeto do adaptador, que mapeia pelo menos um byte e no máximo uma página. Para obter mais informações sobre registros de mapa e o uso de buffers comuns, consulte Objetos do adaptador e DMA.

Alalocando memória com ExAllocatePoolWithTag

Os drivers também podem chamar ExAllocatePoolWithTag, especificando um dos seguintes valores definidos pelo sistema de POOL_TYPE para o parâmetro PoolType:

  • Tipo de Piscina = NonPagedPool para quaisquer objetos ou recursos não armazenados em uma extensão de dispositivo ou extensão de controlador que o driver pode acessar enquanto está sendo executado no IRQL > APC_LEVEL.

    Para esse valor PoolType , ExAllocatePoolWithTag aloca a quantidade de memória que é solicitada se o especificado NumberOfBytes for menor ou igual a PAGE_SIZE. Caso contrário, quaisquer bytes restantes na última página alocada são desperdiçados: inacessíveis para o chamador e inutilizáveis por outro código de modo kernel.

    Por exemplo, em um x86, uma solicitação de alocação de 5 kilobytes (KB) retorna duas páginas de 4 KB. Os últimos 3 KB da segunda página não estão disponíveis para o chamador ou outro chamador. Para evitar o desperdício de pool não paginado, o driver deve alocar várias páginas eficientemente. Neste caso, por exemplo, o driver poderia fazer duas alocações, uma para PAGE_SIZE e outra para 1 KB, para alocar um total de 5 KB.

    Observação A partir do Windows Vista, o sistema adiciona automaticamente a memória adicional para que duas alocações sejam desnecessárias.

  • PoolType = PagedPool para memória que é sempre acedida em IRQL <= APC_LEVEL e não está na via de escrita do sistema de ficheiros.

ExAllocatePoolWithTag retorna um ponteiro NULL se não puder alocar o número solicitado de bytes. Os motoristas devem sempre verificar o ponteiro retornado. Se seu valor for NULL, a rotina DriverEntry (ou qualquer outra rotina de driver que retorna valores NTSTATUS) deve retornar STATUS_INSUFFICIENT_RESOURCES ou manipular a condição de erro, se possível.