Função NdisMAllocateSharedMemory (ndis.h)
Cuidado
Para processadores ARM e ARM64, é altamente recomendável que os gravadores de driver NDIS usem dma WDF ou DMA WDM em vez de DMA de dispersão/coleta de NDIS.
Para obter mais informações sobre o AMD WDF, consulte Manipulando operações de DMA em drivers KMDF.
Para obter mais informações sobre o AMD do WDM, consulte os tópicos filho relacionados ao DMA de Gerenciamento de entrada/saída para drivers.
NdisMAllocateSharedMemory aloca e mapeia um intervalo de memória de host para que o intervalo de memória seja acessível simultaneamente do sistema host e de uma NIC de DMA.
Sintaxe
void NdisMAllocateSharedMemory(
[in] NDIS_HANDLE MiniportAdapterHandle,
[in] ULONG Length,
[in] BOOLEAN Cached,
[out] PVOID *VirtualAddress,
[out] PNDIS_PHYSICAL_ADDRESS PhysicalAddress
);
Parâmetros
[in] MiniportAdapterHandle
Especifica a entrada do identificador para MiniportInitializeEx.
[in] Length
Especifica o número de bytes para alocar.
[in] Cached
Esse parâmetro é ignorado (a memória armazenada em cache sempre é usada em sistemas x86 e x64).
[out] VirtualAddress
Ponteiro para uma variável fornecida pelo chamador na qual essa função retorna o endereço virtual base da alocação para uso pelo driver de miniporto. Se NdisMAllocateSharedMemory não puder atender ao chamador, ele retornará NULL para indicar que nenhuma memória foi alocada.
[out] PhysicalAddress
Ponteiro para uma variável fornecida pelo chamador na qual essa função retorna um endereço físico, adequado para uso pela NIC, que corresponde ao retornado em VirtualAddress ou retorna NULL.
Retornar valor
Nenhum
Comentários
NdisMAllocateSharedMemory fornece o intervalo de endereços virtuais mapeado que o driver usa para acessar o bloco de memória compartilhado e o intervalo de tipo NDIS_PHYSICAL_ADDRESS usado pela NIC. Um valor retornado em PhysicalAddress pode ser duplamente mapeado pelo sistema. Ou seja, um intervalo de endereços "físico" descrito pelo valor em PhysicalAddress e Length pode ser um intervalo de endereços lógicos mapeados que não correspondem aos endereços físicos do host para a alocação em todas as plataformas possíveis.
NdisMAllocateSharedMemory só pode ser chamado de MiniportInitializeEx. O tamanho de uma alocação a ser solicitada depende de como o gravador de driver, conhecendo as funcionalidades e os recursos da NIC, decide fazer a compensação entre o seguinte desempenho versus dilema de tamanho:
-
Em períodos de alto tráfego de rede, um driver de miniporta não poderá manter alta taxa de transferência de E/S se ele for executado com pouco espaço de memória compartilhado para buffers de dados acessíveis ao dispositivo.
Por exemplo, o driver de miniporto pode estar indicando buffers de recebimento na memória compartilhada mais rapidamente do que esses buffers estão sendo retornados de drivers de protocolo associados quando uma inundação de recebimentos chega a uma NIC. Se todo o espaço de memória compartilhado for consumido por buffers de recebimento pendentes, o driver de miniporto poderá ter que desabilitar o recebimento de interrupções em uma NIC até que tenha algum espaço de memória compartilhado disponível para buffers de recebimento.
- Por outro lado, chamar NdisMAllocateSharedMemory com um Length escolhido para prever alguma demanda máxima de transferência torna a imagem do driver maior e seu uso de recursos bastante não econômico, exceto por períodos raros de demanda de E/S muito alta. Além disso, NdisMAllocateSharedMemory pode não dar ao driver um bloco tão grande se a memória insuficiente do sistema estiver disponível, forçando o driver a falhar na inicialização.
NdisMAllocateSharedMemory e NdisMAllocateSharedMemoryAsyncEx são as únicas funções NdisXxx que podem ser chamadas para alocar memória de host que é compartilhada entre o driver, que usa endereços virtuais e uma NIC, que usa os endereços lógicos correspondentes.
Um driver de miniporta deve alinhar os buffers alocados da memória armazenada em cache compartilhada em um integral do limite de linha de cache de dados do host para evitar a divisão da linha de cache durante o AMD. A divisão de linha de cache pode causar problemas de integridade de dados no driver ou degradar o desempenho de E/S do driver (e do sistema), exigindo liberação excessiva de cache de dados para manter a integridade dos dados. MiniportInitializeEx pode chamar NdisMGetDmaAlignment para determinar o limite de alinhamento na plataforma atual para buffers acessíveis ao dispositivo que o driver configurará dentro de um intervalo alocado de memória compartilhada.
Um driver de miniporta deve definir um limite de quanta memória compartilhada ele pode alocar. Esse limite é específico do driver e deve ser alto o suficiente para que o driver não fique sem buffers. Não defina um limite excessivamente alto, pois isso pode resultar em um consumo desperdiçado de memória compartilhada que poderia reduzir o desempenho do sistema.
MiniportInitializeEx também pode chamar NdisSystemProcessorCount antes de chamar NdisMAllocateSharedMemory se o gravador de driver decidir alocar um bloco de memória compartilhado maior em computadores multiprocessadores, pressupõe que qualquer computador SMP provavelmente será um servidor de rede com maiores demandas de transferência de rede na NIC do que uma estação de trabalho.
Se sua chamada para NdisMAllocateSharedMemory falhar, MiniportInitializeEx poderá chamar novamente solicitando uma alocação menor. No entanto, se MiniportInitializeEx não puder alocar memória compartilhada suficiente para a NIC, ele deverá liberar todos os recursos já alocados e falhar na inicialização.
Se o driver de miniporta indicar posteriormente recebimentos com NdisMIndicateReceiveNetBufferLists, ele deve alocar alguns descritores de buffer do pool de buffers que mapeiam os buffers de recebimento da NIC no bloco de memória compartilhada.
Se a memória alocada estiver armazenada em cache e, portanto, precisar ser liberada em transferências, o driver de miniporto deverá chamar NdisAllocateMdl para alocar um descritor de tipo NDIS_BUFFER para o intervalo de memória compartilhado. O driver de miniporto deve chamar KeFlushIoBuffers com esse descritor de buffer para executar essa liberação.
Se um driver de miniporta chamar NdisMAllocateSharedMemoryAsyncEx ou NdisMAllocateSharedMemory, ele deve liberar todas as alocações pendentes com uma ou mais chamadas para NdisMFreeSharedMemory quando uma NIC é removida, ou seja, quando sua função MiniportHaltEx é chamada.
Requisitos
Requisito | Valor |
---|---|
Cliente mínimo com suporte | Com suporte no NDIS 6.0 e posterior. |
Plataforma de Destino | Universal |
Cabeçalho | ndis.h (inclua Ndis.h) |
Biblioteca | Ndis.lib |
IRQL | PASSIVE_LEVEL |