Uso degli elenchi Lookaside

I driver che devono allocare i buffer a dimensioni fisse in modo dinamico per eseguire operazioni di I/O su richiesta possono usare le routine di supporto di ExXxxLookasideListEx o Ex Xxx LookasideList. Dopo che un driver inizializza il suo elenco lookaside, il sistema operativo conterrà alcuni buffer allocati dinamicamente delle dimensioni specificate nell'elenco lookaside del driver, riservando in modo efficace un set di buffer di dimensioni fisse riutilizzabili per il driver. Il formato e il contenuto dei buffer fissi di un driver (noti anche come voci) nell'elenco lookaside sono determinati dal driver.

Ad esempio, i driver di classe di archiviazione che devono configurare blocchi di richiesta SCSI (SRB) per i driver di porta/miniport sottostanti SCSI usano elenchi lookaside. Tale driver di classe alloca i buffer per gli SRB in base alle esigenze dall'elenco lookaside e rilascia ogni buffer SRB nell'elenco lookaside per il riutilizzo dell'elenco lookaside ogni volta che viene restituito un SRB nel driver di classe in un'IRP completata. Poiché un driver di classe di archiviazione non può preconfigurare il numero di SRB che deve usare in qualsiasi momento perché la domanda di I/O sul driver aumenta e cade, un elenco lookaside è un modo pratico ed economico per gestire l'allocazione e la deallocazione dei buffer per le SRB di dimensioni fisse in tale driver.

Il sistema operativo gestisce lo stato di tutti gli elenchi lookaside impaginati e non impaginati attualmente usati, monitorando dinamicamente la domanda di allocazioni e deallocazione delle voci in tutti gli elenchi e del pool di sistema disponibile per le nuove voci. Quando la domanda di allocazioni è elevata, il sistema operativo aumenta il numero di voci che contiene in ogni elenco lookaside. Quando la domanda scende di nuovo, libera le voci lookaside lookaside tornano al pool di sistema.

Gli elenchi lookaside sono thread-safe. Un elenco lookaside include una sincronizzazione predefinita per abilitare più thread contemporaneamente in esecuzione in un driver per condividere un elenco lookaside. Questi thread possono allocare in modo sicuro i buffer dall'elenco lookaside condiviso e liberare questi buffer all'elenco senza richiedere al driver di sincronizzare in modo esplicito queste operazioni. Tuttavia, per evitare possibili perdite di dati e danneggiamento dei dati, un set di thread che condividono un elenco lookaside deve sincronizzare esplicitamente l'inizializzazione e l'eliminazione dell'elenco.

Interfacce di elenco lookaside

A partire da Windows Vista, la struttura LOOKASIDE_LIST_EX descrive un elenco lookaside che può contenere buffer paginati o non di pagina. Se un driver fornisce routine allocate e gratuite personalizzate per questo elenco lookaside, queste routine ricevono un contesto privato come parametro di input. Un driver può usare questo contesto per raccogliere dati privati per l'elenco lookaside. Ad esempio, il contesto può essere usato per contare il numero di voci di elenco allocate dinamicamente e liberate dall'elenco. Per un esempio di codice che illustra come usare un contesto in questo modo, vedere ExInitializeLookasideListEx.

Le routine fornite dal sistema seguenti supportano elenchi lookaside descritti da una struttura LOOKASIDE_LIST_EX :

ExAllocateFromLookasideListEx

ExDeleteLookasideListEx

ExFlushLookasideListEx

ExFreeToLookasideListEx

ExInitializeLookasideListEx

A partire da Windows 2000, la struttura PAGED_LOOKASIDE_LIST descrive un elenco lookaside contenente buffer paginati. Se un driver fornisce routine di allocazione e gratuite personalizzate per questo elenco lookaside, queste routine non ricevono un contesto privato come parametro di input. Per questo motivo, se il driver è destinato a essere eseguito solo in Windows Vista e versioni successive di Windows, prendere in considerazione l'uso della struttura LOOKASIDE_LIST_EX anziché la struttura PAGED_LOOKASIDE_LIST per gli elenchi lookaside . Le routine fornite dal sistema seguenti supportano elenchi lookaside descritti da una struttura PAGED_LOOKASIDE_LIST :

ExAllocateFromPagedLookasideList

ExDeletePagedLookasideList

ExFreeToPagedLookasideList

ExInitializePagedLookasideList

A partire da Windows 2000, la struttura NPAGED_LOOKASIDE_LIST descrive un elenco lookaside contenente buffer non di pagina. Se un driver fornisce routine di allocazione e gratuite personalizzate per questo elenco lookaside, queste routine non ricevono un contesto privato come parametro di input. Anche in questo caso, se il driver è destinato a essere eseguito solo in Windows Vista e versioni successive di Windows, è consigliabile usare la struttura LOOKASIDE_LIST_EX anziché la struttura NPAGED_LOOKASIDE_LIST per gli elenchi lookaside. Le routine fornite dal sistema seguenti supportano elenchi lookaside descritti da una struttura NPAGED_LOOKASIDE_LIST :

ExAllocateFromNPagedLookasideList

ExDeleteNPagedLookasideList

ExFreeToNPagedLookasideList

ExInitializeNPagedLookasideList

Linee guida per l'implementazione

Per implementare un elenco lookaside che usa una struttura LOOKASIDE_LIST_EX , seguire queste linee guida di progettazione:

  • Chiamare ExInitializeLookasideListEx per configurare un elenco lookaside. In questa chiamata specificare se le voci nell'elenco lookaside devono essere paged o buffer non di pagina. Usare buffer non di pagina se il driver stesso o qualsiasi driver sottostante a cui passa le voci dell'elenco lookaside potrebbe accedere a queste voci in IRQL >= DISPATCH_LEVEL. Usare i buffer con pagina solo se gli accessi alle voci dell'elenco lookaside del driver si verificano sempre in IRQL <= APC_LEVEL.

  • La struttura LOOKASIDE_LIST_EX per l'elenco lookaside deve sempre risiedere nella memoria di sistema non con pagine, indipendentemente dal fatto che le voci nell'elenco siano paginate o non paginate.

  • Per prestazioni migliori, passare i puntatori NULL per i parametri Allocate e Free a ExInitializeLookasideListEx a meno che le routine di allocazione e deallocation non debbano eseguire più di allocare e liberare memoria per le voci di elenco lookaside. Ad esempio, queste routine potrebbero registrare informazioni sull'utilizzo del driver di buffer allocati dinamicamente.

  • Una routine allocata fornita dal driver può passare i parametri di input (PoolType, Tag e Size) ricevuti direttamente alla routine ExAllocatePoolWithTag o ExAllocatePoolWithQuotaTag per allocare un nuovo buffer.

  • Per ogni chiamata a ExAllocateFromLookasideListEx, effettuare la chiamata reciproca a ExFreeToLookasideListEx appena possibile ogni volta che non viene più utilizzata una voce allocata in precedenza.

La fornitura di routine Allocate e Free che non fanno altro che chiamare ExAllocatePoolWithTag e ExFreePool, rispettivamente, i cicli di elaborazione dei rifiuti. ExAllocateFromLookasideListEx effettua le chiamate necessarie a ExAllocatePoolWithTag e ExFreePool automaticamente quando un driver passa i puntatori NULLAllocate e Free a ExInitializeLookasideListEx.

Qualsiasi routine di allocazione fornita da driver non deve allocare memoria per una voce dal pool con pagine da tenere in un elenco lookaside non di pagina o viceversa. Deve anche allocare voci di dimensioni fisse, perché qualsiasi chiamata del driver successiva a ExAllocateFromLookasideListEx restituisce la prima voce attualmente contenuta nell'elenco lookaside a meno che l'elenco non sia vuoto. Di conseguenza, una chiamata a ExAllocateFromLookasideListEx causa una chiamata alla routine Allocate fornita dal driver solo se l'elenco lookaside specificato è attualmente vuoto. Pertanto, in ogni chiamata a ExAllocateFromLookasideListEx, la voce restituita sarà esattamente la dimensione necessaria dal driver solo se tutte le voci nell'elenco lookaside sono di dimensioni fisse. Una routine allocata fornita dal driver non deve anche modificare il valore tag passato originariamente a ExInitializeLookasideListEx, perché le modifiche apportate al valore del tag del pool renderebbero più difficile il debug e il rilevamento dell'utilizzo della memoria del driver.

Chiamate all'archivio ExFreeToLookasideListEx precedentemente allocato nell'elenco lookaside, a meno che l'elenco non sia già completo , ovvero l'elenco contiene il numero massimo massimo determinato dal sistema. Per migliorare le prestazioni, un driver deve effettuare una chiamata reciproca a ExFreeToLookasideListEx il più rapidamente possibile per ogni chiamata eseguita a ExAllocateFromLookasideListEx. Quando un driver libera rapidamente le voci all'elenco lookaside, la chiamata successiva del driver a ExAllocateFromLookasideListEx è molto meno probabile che venga addebitata la penalità delle prestazioni per l'allocazione dinamica della memoria per una nuova voce.

Linee guida simili si applicano a un elenco lookaside che usa una struttura PAGED_LOOKASIDE_LIST o NPAGED_LOOKASIDE_LIST .