Funzione NdisMAllocateSharedMemory (ndis.h)
Attenzione
Per i processori ARM e ARM64, è consigliabile che i writer di driver NDIS usino WDF DMA o WDM DMA anziché NDIS Scatter/Gather DMA.
Per altre informazioni su WDF DMA, vedere Gestione delle operazioni DMA nei driver KMDF.
Per altre informazioni su WDM DMA, vedere gli argomenti figlio correlati a DMA relativi alla gestione dell'input/output per i driver.
NdisMAllocateSharedMemory alloca e esegue il mapping di un intervallo di memoria host in modo che l'intervallo di memoria sia accessibile contemporaneamente dal sistema host e da una scheda di interfaccia di rete DMA.
Sintassi
void NdisMAllocateSharedMemory(
[in] NDIS_HANDLE MiniportAdapterHandle,
[in] ULONG Length,
[in] BOOLEAN Cached,
[out] PVOID *VirtualAddress,
[out] PNDIS_PHYSICAL_ADDRESS PhysicalAddress
);
Parametri
[in] MiniportAdapterHandle
Specifica l'input dell'handle per MiniportInitializeEx.
[in] Length
Specifica il numero di byte da allocare.
[in] Cached
Questo parametro viene ignorato (la memoria memorizzata nella cache viene sempre usata nei sistemi x86 e x64).
[out] VirtualAddress
Puntatore a una variabile fornita dal chiamante in cui questa funzione restituisce l'indirizzo virtuale di base dell'allocazione da usare dal driver miniport. Se NdisMAllocateSharedMemory non può soddisfare il chiamante, restituisce NULL per indicare che non è stata allocata alcuna memoria.
[out] PhysicalAddress
Puntatore a una variabile fornita dal chiamante in cui questa funzione restituisce un indirizzo fisico, adatto per l'uso dalla scheda di interfaccia di rete, che corrisponde a quello restituito in VirtualAddress o restituisce NULL.
Valore restituito
nessuno
Osservazioni
NdisMAllocateSharedMemory fornisce sia l'intervallo di indirizzi virtuali mappato usato dal driver per accedere al blocco di memoria condivisa sia all'intervallo di tipo NDIS_PHYSICAL_ADDRESS utilizzato dalla scheda di interfaccia di rete. Un valore restituito in PhysicalAddress può essere mappato manualmente dal sistema. Ovvero, un intervallo di indirizzi "fisico" descritto dal valore in PhysicalAddress e Length può essere un intervallo di indirizzi logici mappati che non corrispondono agli indirizzi fisici host per l'allocazione in ogni possibile piattaforma.
NdisMAllocateSharedMemory può essere chiamato solo da MiniportInitializeEx. La dimensione di un'allocazione da richiedere dipende dal modo in cui il writer del driver, conoscendo le funzionalità e le funzionalità della scheda di interfaccia di rete, decide di fare il compromesso tra le prestazioni seguenti e il dilemma delle dimensioni seguenti:
-
In periodi di traffico di rete elevato, un driver miniport non può mantenere una velocità effettiva di I/O elevata se viene eseguito in uno spazio di memoria condiviso insufficiente per i buffer di dati accessibili dal dispositivo.
Ad esempio, il driver miniport potrebbe indicare che i buffer di ricezione nella memoria condivisa vengono restituiti più velocemente di tali buffer dai driver di protocollo associati quando un flusso di ricezione arriva a una scheda di interfaccia di rete. Se tutto lo spazio di memoria condiviso viene utilizzato dai buffer di ricezione in attesa, il driver miniport potrebbe dover disabilitare gli interrupt di ricezione in una scheda di interfaccia di rete fino a quando non dispone di spazio di memoria condiviso disponibile per i buffer di ricezione.
- D'altra parte, la chiamata a NdisMAllocateSharedMemory con una lunghezza scelta per prevedere una domanda massima di trasferimento rende l'immagine del driver più grande e il suo utilizzo delle risorse piuttosto non geografico, tranne per periodi rari di domanda di I/O molto elevata. Inoltre , NdisMAllocateSharedMemory potrebbe non fornire al driver un blocco di grandi dimensioni se è disponibile memoria di sistema insufficiente, forzando l'inizializzazione del driver.
NdisMAllocateSharedMemory e NdisMAllocateSharedMemoryAsyncEx sono le uniche funzioni NdisXxx che possono essere chiamate per allocare memoria host condivisa tra il driver, che usa indirizzi virtuali e una scheda di interfaccia di rete, che usa gli indirizzi logici corrispondenti.
Un driver miniport deve allineare i buffer allocati dalla memoria condivisa memorizzata nella cache in un integrale del limite della riga di cache dei dati host per impedire l'applicazione della riga di cache durante DMA. La disinstallazione della riga della cache può causare problemi di integrità dei dati nel driver o ridurre le prestazioni di I/O del driver (e del sistema) richiedendo un eccessivo scaricamento della cache dei dati per mantenere l'integrità dei dati. MiniportInitializeEx può chiamare NdisMGetDmaAlignment per determinare il limite di allineamento nella piattaforma corrente per i buffer accessibili dal dispositivo configurati dal driver all'interno di un intervallo allocato di memoria condivisa.
Un driver miniport deve impostare un limite sulla quantità di memoria condivisa che può allocare. Questo limite è specifico del driver e deve essere sufficientemente elevato in modo che il driver non esaurisca i buffer. Non impostare un limite eccessivamente elevato, perché ciò potrebbe comportare un consumo di memoria condivisa sprecato che potrebbe ridurre le prestazioni del sistema.
MiniportInitializeEx potrebbe anche chiamare NdisSystemProcessorCount prima di chiamare NdisMAllocateSharedMemory se il writer del driver decide di allocare un blocco di memoria condiviso più grande nei computer multiprocessore presupponendo che qualsiasi computer SMP sia probabilmente un server di rete con richieste di trasferimento di rete più elevate nella scheda di interfaccia di rete rispetto a una workstation.
Se la chiamata a NdisMAllocateSharedMemory ha esito negativo, MiniportInitializeEx può chiamare di nuovo richiedendo un'allocazione più piccola. Tuttavia, se MiniportInitializeEx non può allocare memoria condivisa sufficiente per la scheda di interfaccia di rete, deve rilasciare tutte le risorse già allocate e non riuscire l'inizializzazione.
Se successivamente il driver miniport indica che riceve con NdisMIndicateReceiveNetBufferLists, deve allocare un certo numero di descrittori di buffer dal pool di buffer che eseguono il mapping dei buffer di ricezione della scheda di interfaccia di rete nel blocco di memoria condivisa.
Se la memoria allocata viene memorizzata nella cache e pertanto deve essere scaricata sui trasferimenti, il driver miniport deve chiamare NdisAllocateMdl per allocare un descrittore di tipo NDIS_BUFFER per l'intervallo di memoria condivisa. Il driver miniport deve chiamare KeFlushIoBuffers con questo descrittore di buffer per eseguire tale scaricamento.
Se un driver miniport chiama NdisMAllocateSharedMemoryAsyncEx o NdisMAllocateSharedMemory, deve rilasciare tutte le allocazioni in sospeso con una o più chiamate a NdisMFreeSharedMemory quando viene rimossa una scheda di interfaccia di rete, ovvero quando viene chiamata la relativa funzione MiniportHaltEx .
Requisiti
Requisito | Valore |
---|---|
Client minimo supportato | Supportato in NDIS 6.0 e versioni successive. |
Piattaforma di destinazione | Universale |
Intestazione | ndis.h (include Ndis.h) |
Libreria | Ndis.lib |
IRQL | PASSIVE_LEVEL |