Condividi tramite


Scaricamento dei dati memorizzati nella cache durante le operazioni DMA

In alcune piattaforme, il processore e il controller DMA di sistema (o adattatori DMA master del bus) presentano anomalie di coerenza della cache. Le linee guida seguenti consentono ai driver che usano la versione 1 o 2 dell'interfaccia operativa DMA (vedere DMA_OPERATIONS) di mantenere gli stati della cache coerenti in tutte le architetture del processore supportate, incluse le architetture che non contengono hardware per applicare automaticamente la coerenza della cache.

Nota Le linee guida contenute in questo argomento si applicano solo ai driver che usano le versioni 1 e 2 dell'interfaccia operativa DMA. I driver che usano la versione 3 di questa interfaccia devono seguire un set diverso di linee guida. Per altre informazioni, vedere La versione 3 dell'interfaccia operativa DMA.

Per mantenere l'integrità dei dati durante le operazioni DMA, i driver di livello più basso devono seguire queste linee guida

  1. Chiamare KeFlushIoBuffers prima di iniziare un'operazione di trasferimento per mantenere la coerenza tra i dati che potrebbero essere memorizzati nella cache nel processore e i dati in memoria.

    Se un driver chiama AllocateCommonBuffer con il parametro CacheEnabled impostato su TRUE, il driver deve chiamare KeFlushIoBuffers prima di iniziare un'operazione di trasferimento da e verso il relativo buffer.

  2. Chiamare FlushAdapterBuffers alla fine di ogni operazione di trasferimento del dispositivo per assicurarsi che tutti i byte rimanenti nei buffer del controller DMA di sistema siano stati scritti in memoria o nel dispositivo subordinato.

    In alternativa, chiamare FlushAdapterBuffers alla fine di ogni operazione di trasferimento per assicurarsi che tutti i dati siano stati letti nella memoria di sistema o scritti in un dispositivo bus-master DMA.

La figura seguente illustra perché è importante scaricare la cache del processore prima di un'operazione di lettura o scrittura usando DMA se il processore host e il controller DMA non mantengono automaticamente la coerenza della cache.

diagramma che illustra le operazioni di lettura e scrittura tramite dma.

Un'operazione di lettura o scrittura DMA asincrona accede ai dati in memoria, non nella cache del processore. A meno che questa cache non sia stata scaricata chiamando KeFlushIoBuffers poco prima di una lettura, i dati trasferiti nella memoria di sistema dall'operazione DMA potrebbero essere sovrascritti con dati non aggiornati se la cache del processore viene scaricata in un secondo momento. A meno che la cache del processore non sia stata scaricata chiamando KeFlushIoBuffers poco prima di una scrittura, i dati in questa cache potrebbero essere più up-to-date rispetto alla copia in memoria.

KeFlushIoBuffers non esegue alcuna operazione se il processore e il controller DMA possono essere basati su per mantenere la coerenza della cache, quindi le chiamate a questa routine di supporto non hanno quasi alcun sovraccarico in tale piattaforma.

Come illustrato anche nella figura precedente, i controller DMA, rappresentati da oggetti adapter, possono avere buffer interni. Un controller DMA di questo tipo può trasferire i dati memorizzati nella cache in blocchi a dimensione fissa, in genere otto o più byte alla volta. Inoltre, questi controller DMA possono attendere il completamento dei buffer interni prima di ogni operazione di trasferimento.

Si consideri il caso di un driver di livello più basso che usa DMA subordinato per leggere i dati in blocchi di dimensioni variabili o in blocchi a dimensione fissa che non sono un multiplo integrale delle dimensioni della cache di un controller DMA di sistema. A meno che questo driver non chiami FlushAdapterBuffers alla fine di ogni trasferimento del dispositivo, non può essere sicuro quando ogni byte richiesto verrà effettivamente trasferito.

Il driver di un dispositivo DMA master del bus dovrebbe anche invocare FlushAdapterBuffers al termine di ogni operazione di trasferimento di un IRP, per garantire che tutti i dati siano stati trasferiti nella memoria di sistema o verso il dispositivo.

FlushAdapterBuffers restituisce un valore booleano che indica se l'operazione di scaricamento richiesta ha avuto esito positivo. Un driver può usare questo valore per determinare come impostare il blocco di stato di I/O quando si completa un IRP per un'operazione di lettura o scrittura DMA.