Condividi tramite


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

Nota Un driver miniport deve avere già chiamato NdisMRegisterScatterGatherDma o NdisMRegisterDmaChannel per inizializzare un canale DMA a dispersione/gather prima di chiamare NdisMAllocateSharedMemory.
 
Microsoft Windows Server 2003, Windows XP Service Pack 1 e versioni successive di Windows consentono alle schede di interfaccia di rete DMA master del bus e alle schede di interfaccia di rete DMA subordinate di chiamare NdisMAllocateSharedMemory. Le versioni precedenti consentono solo alle schede di interfaccia di rete DMA master del bus di chiamare NdisMAllocateSharedMemory. In queste versioni precedenti, se MiniportInitializeEx non ha specificato che la scheda di interfaccia di rete è un master del bus quando viene chiamata NdisMSetMiniportAttributes, NdisMAllocateSharedMemory restituisce semplicemente il controllo senza tentare di effettuare un'allocazione.

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.
Un conducente miniport che fornisce un La funzione MiniportSharedMemoryAllocateComplete offre una notevole flessibilità nella risoluzione delle prestazioni precedenti rispetto al dilemma delle dimensioni. MiniportInitializeEx deve allocare solo memoria condivisa sufficiente con NdisMAllocateSharedMemory per una moderata richiesta di operazioni di trasferimento di rete tramite la scheda di interfaccia di rete se il driver ha una funzione MiniportSharedMemoryAllocateComplete . Tale driver miniport può chiamare NdisMAllocateSharedMemoryAsyncEx dinamicamente per allocare più memoria condivisa in periodi di richiesta di trasferimento più pesante su una scheda di interfaccia di rete. Quando la domanda elevata per i trasferimenti diminuisce, tale driver chiama NdisMFreeSharedMemory per rilasciare la memoria aggiuntiva allocata. Si noti che solo le schede di interfaccia di rete DMA master bus possono chiamare NdisMAllocateSharedMemoryAsyncEx ed esportare MiniportSharedMemoryAllocateComplete. Questa funzionalità non è supportata per le schede di interfaccia di rete DMA subordinate.

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

Vedi anche

KeFlushIoBuffers

MiniportHaltEx

MiniportInitializeEx

MiniportSharedMemoryAllocateComplete

NdisAllocateMdl

NdisMAllocateNetBufferSGList

NdisMAllocateSharedMemoryAsyncEx

NdisMFreeSharedMemory

NdisMGetDmaAlignment

NdisMIndicateReceiveNetBufferLists

NdisMSetMiniportAttributes

NdisSystemProcessorCount