Share via


Uso di I/O diretto con PIO

Un driver che usa I/O programmato anziché DMA deve eseguire il mapping dei buffer dello spazio utente in un intervallo di indirizzi dello spazio di sistema. Nella figura seguente viene illustrato come il gestore I/O configura una richiesta di IRP_MJ_READ per un'operazione di trasferimento PIO che usa l'I/O diretta.

diagramma che illustra l'i/o diretto per i dispositivi che usano pio.

La figura mostra come un dispositivo che usa PIO gestisce la stessa attività.

  1. Un intervallo di indirizzi virtuali nello spazio utente rappresenta il buffer del thread corrente e il contenuto del buffer potrebbe essere effettivamente archiviato in un certo numero di pagine fisicamente disconti. Se la lunghezza del buffer è diversa da zero, la gestione I/O crea un MDL per descrivere questo buffer.

  2. Gestione I/O consente di gestire la richiesta di lettura del thread corrente, per cui il thread passa un intervallo di indirizzi virtuali nello spazio utente che rappresentano un buffer.

  3. Gestione I/O o FSD controlla il buffer fornito dall'utente per l'accessibilità. Se il gestore di I/O ha creato un MDL, chiama MmProbeAndLockPages con un MDL, che specifica l'intervallo di indirizzi virtuali per il buffer utente. MmProbeAndLockPages inserisce anche l'intervallo di indirizzi fisici corrispondente nell'MDL.

  4. La gestione I/O fornisce un puntatore all'MDL (MdlAddress) in un'istanza di IRP che richiede un'operazione di trasferimento. Fino a quando il gestore di I/O o il file system chiama MmUnlockPages dopo il completamento dell'IRP, le pagine fisiche descritte nel file MDL rimangono bloccate e assegnate al buffer. Tuttavia, gli indirizzi virtuali in tale MDL possono diventare invisibili (e non validi), anche prima che l'IRP venga inviato al driver del dispositivo o a qualsiasi driver intermedio che potrebbe essere stratiato sopra il driver del dispositivo.

  5. Se il driver richiede indirizzi di sistema (virtuale), il driver chiama MmGetSystemAddressForMdlSafe con il puntatore MdlAddress di IRP per eseguire il mapping degli indirizzi virtuali nello spazio utente in un intervallo di indirizzi dello spazio di sistema. Nella figura precedente AliasBuff rappresenta l'MDL che descrive gli indirizzi con mapping doubly.

  6. Il driver usa l'intervallo di indirizzi virtuali dello spazio di sistema dal MDL mappato doubly (AliasBuff) per leggere i dati in memoria.

Quando il driver completa l'IRP chiamando IoCompleteRequest, gestione I/O o file system rilascia l'intervallo di spazio di sistema mappato doubly del MDL se il driver denominato MmGetSystemAddressForMdlSafe. La gestione I/O o il file system sblocca le pagine descritte in MDL e elimina MDL e IRP per conto del driver. Per migliorare le prestazioni, i driver devono evitare il mapping degli indirizzi fisici MDL allo spazio di sistema, come descritto nel passaggio 3, a meno che non debbano usare indirizzi virtuali. In questo modo vengono usate voci di tabella della pagina di sistema inutilmente e possono ridurre sia le prestazioni del driver che la scalabilità. Inoltre, il sistema potrebbe arrestare l'arresto anomalo se viene esaurito dalle voci della tabella di pagina, perché la maggior parte dei driver meno recenti non può gestire questa situazione.

I buffer del thread utente corrente e il thread stesso devono essere residenti nella memoria fisica solo mentre il thread è corrente. Per il thread illustrato nella figura precedente, il contenuto del buffer utente può essere visualizzato nell'archiviazione secondaria mentre vengono eseguiti thread di un altro processo. Quando viene eseguito un altro thread del processo, la memoria fisica del sistema per il buffer del thread richiesto può essere sovrascritta a meno che la gestione memoria non abbia bloccato e mantenuto le pagine fisiche corrispondenti che contengono il buffer del thread originale.

Tuttavia, gli indirizzi virtuali del thread originale per il buffer non rimangono visibili mentre un altro thread è corrente, anche se la gestione memoria mantiene le pagine fisiche del buffer. Di conseguenza, i driver non possono usare un indirizzo virtuale restituito da MmGetMdlVirtualAddress per accedere alla memoria. I chiamanti di questa routine devono passare i risultati a MapTransfer (insieme al puntatore MdlAddress di IRP) per trasferire i dati usando il sistema basato su pacchetti o DMA master del bus.