Partilhar via


Liberando dados armazenados em cache durante operações de DMA

Em algumas plataformas, o controlador de DMA do processador e do sistema (ou adaptadores de DMA master barramento) exibe anomalias de coerência de cache. As diretrizes a seguir permitem que os drivers que usam a versão 1 ou 2 da interface de operações de DMA (consulte DMA_OPERATIONS) mantenham estados de cache coerentes em todas as arquiteturas de processador com suporte, incluindo arquiteturas que não contêm hardware para impor automaticamente a coerência de cache.

Nota As diretrizes neste tópico se aplicam somente aos drivers que usam as versões 1 e 2 da interface de operações de DMA. Os drivers que usam a versão 3 dessa interface devem seguir um conjunto diferente de diretrizes. Para obter mais informações, consulte Versão 3 da Interface de Operações de DMA.

Para manter a integridade dos dados durante as operações de DMA, os drivers de nível mais baixo devem seguir estas diretrizes

  1. Chame KeFlushIoBuffers antes de iniciar uma operação de transferência para manter a consistência entre os dados que podem ser armazenados em cache no processador e os dados na memória.

    Se um driver chamar AllocateCommonBuffer com o parâmetro CacheEnabled definido como TRUE, o driver deverá chamar KeFlushIoBuffers antes de iniciar uma operação de transferência de/para seu buffer.

  2. Chame FlushAdapterBuffers no final de cada operação de transferência de dispositivo para garantir que todos os bytes restantes nos buffers do controlador DMA do sistema tenham sido gravados na memória ou no dispositivo subordinado.

    Ou chame FlushAdapterBuffers no final de cada operação de transferência para que um determinado IRP verifique se todos os dados foram lidos na memória do sistema ou gravados em um dispositivo DMA master barramento.

A figura a seguir mostra por que é importante liberar o cache do processador antes de uma operação de leitura ou gravação usando DMA se o processador host e o controlador de DMA não mantiverem automaticamente a coerência do cache.

diagrama ilustrando operações de leitura e gravação usando dma.

Uma operação de leitura ou gravação de DMA assíncrona acessa dados na memória, não no cache do processador. A menos que esse cache tenha sido liberado chamando KeFlushIoBuffers pouco antes de uma leitura, os dados transferidos para a memória do sistema pela operação DMA poderão ser substituídos com dados obsoletos se o cache do processador for liberado mais tarde. A menos que o cache do processador tenha sido liberado chamando KeFlushIoBuffers pouco antes de uma gravação, os dados nesse cache podem estar mais atualizados do que a cópia na memória.

KeFlushIoBuffers não fará nada se o processador e o controlador de DMA puderem ser confiados para manter a coerência do cache, portanto, as chamadas para essa rotina de suporte quase não têm sobrecarga em tal plataforma.

Como também mostrado na figura anterior, os controladores DMA, que são representados por objetos do adaptador, podem ter buffers internos. Esse controlador de DMA pode transferir dados armazenados em cache em partes de tamanho fixo, geralmente oito ou mais bytes por vez. Além disso, esses controladores de DMA podem aguardar até que seus buffers internos estejam cheios antes de cada operação de transferência.

Considere o caso de um driver de nível mais baixo que usa DMA subordinado para ler dados em partes de tamanho variável ou em partes de tamanho fixo que não são um múltiplo integral do tamanho do cache de um controlador de DMA do sistema. A menos que esse driver chame FlushAdapterBuffers no final de cada transferência de dispositivo, ele não pode ter certeza de quando todos os bytes solicitados realmente serão transferidos.

O driver de um dispositivo DMA master ônibus também deve chamar FlushAdapterBuffers no final de cada operação de transferência para um IRP para ter certeza de que todos os dados foram transferidos para a memória do sistema ou para o dispositivo.

FlushAdapterBuffers retorna um valor booliano que indica se a operação de liberação solicitada foi bem-sucedida. Um driver pode usar esse valor para determinar como definir o bloco de E/S status ao concluir um IRP para uma operação de leitura ou gravação de DMA.