Share via


Scaricamento dei dati memorizzati nella cache durante le operazioni DMA

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

Nota Le linee guida di questo argomento si applicano solo ai driver che usano le versioni 1 e 2 dell'interfaccia delle operazioni DMA. I driver che usano la versione 3 di questa interfaccia devono seguire un set diverso di linee guida. Per altre informazioni, vedere Versione 3 dell'interfaccia operazioni 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 verso/dal 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 del 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 in memoria di sistema o scritti in un dispositivo DMA master del bus.

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 coherency della cache.

diagramma che illustra le operazioni di lettura e scrittura usando 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 appena 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 appena prima di una scrittura, i dati in questa cache potrebbero essere più aggiornati rispetto alla copia in memoria.

KeFlushIoBuffers non fa nulla se il processore e il controller DMA possono essere basati su per mantenere la coherency 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 dagli oggetti adapter, possono avere buffer interni. Tale controller DMA può trasferire dati memorizzati nella cache in blocchi di dimensioni fisse, in genere otto o più byte alla volta. Inoltre, questi controller DMA possono attendere fino a quando i buffer interni non sono completi 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 di dimensioni fisse che non sono un multiplo integrale delle dimensioni della cache del 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 deve anche chiamare FlushAdapterBuffers alla fine di ogni operazione di trasferimento per assicurarsi che tutti i dati siano stati trasferiti nella memoria di sistema o fuori dal 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 durante il completamento di un'operazione di lettura O DMA.