Dela via


Rensa cachelagrade data under DMA-åtgärder

På vissa plattformar uppvisar processorn och systemets DMA-styrenhet (eller busshanterar-DMA-adaptrar) cachekoherensavvikelser. Följande riktlinjer gör det möjligt för drivrutiner som använder version 1 eller 2 av DMA-driftgränssnittet (se DMA_OPERATIONS) att upprätthålla sammanhängande cachetillstånd i alla processorarkitekturer som stöds, inklusive arkitekturer som inte innehåller maskinvara för att automatiskt framtvinga cachesammansekvens.

Not Riktlinjerna i det här avsnittet gäller endast för drivrutiner som använder version 1 och 2 av DMA-driftgränssnittet. Drivrutiner som använder version 3 av det här gränssnittet måste följa en annan uppsättning riktlinjer. Mer information finns i Version 3 av DMA-driftgränssnittet.

För att upprätthålla dataintegriteten under DMA-åtgärder måste drivrutiner på lägsta nivå följa dessa riktlinjer

  1. Anropa KeFlushIoBuffers innan du påbörjar en överföringsåtgärd för att upprätthålla konsekvens mellan data som kan cachelagras i processorn och data i minnet.

    Om en drivrutin anropar AllocateCommonBuffer med parametern CacheEnabled inställd på TRUE måste drivrutinen anropa KeFlushIoBuffers innan en överföring till/från bufferten påbörjas.

  2. Anropa FlushAdapterBuffers i slutet av varje enhetsöverföringsåtgärd för att se till att eventuella återstående byte i system-DMA-styrenhetens buffertar har skrivits till minnet eller till den underordnade enheten.

    Eller anropa FlushAdapterBuffers i slutet av varje överföringsåtgärd för en viss IRP för att se till att alla data har lästs in i systemminnet eller skrivits ut till en DMA-enhet med busshanterare.

Följande bild visar varför det är viktigt att tömma processorcachen före en läs- eller skrivåtgärd med hjälp av DMA om värdprocessorn och DMA-styrenheten inte automatiskt upprätthåller cachesammankoppling.

diagram som illustrerar läs- och skrivåtgärder med hjälp av dma.

En asynkron DMA-läs- eller skrivåtgärd kommer åt data i minnet, inte i processorcachen. Om inte den här cachen har tömts genom att anropa KeFlushIoBuffers strax före en läsning kan data som överförs till systemminnet av DMA-åtgärden skrivas över med inaktuella data om processorcachen töms senare. Om inte processorcachen har tömts genom att anropa KeFlushIoBuffers strax före en skrivning, kan data i den här cachen vara mer up-to-date än kopian i minnet.

KeFlushIoBuffers gör ingenting om processorn och DMA-styrenheten kan förlita sig på för att upprätthålla cachesammansekvens, så anrop till den här supportrutinen har nästan inga omkostnader på en sådan plattform.

Som också visas i föregående bild kan DMA-styrenheter, som representeras av adapterobjekt, ha interna buffertar. En sådan DMA-kontrollant kan överföra cachelagrade data i segment med fast storlek, vanligtvis åtta eller fler byte i taget. Dessutom kan dessa DMA-styrenheter vänta tills deras interna buffertar är fulla före varje överföringsåtgärd.

Tänk på fallet med en drivrutin på lägsta nivå som använder underordnad DMA för att läsa data i segment med variabel storlek eller i segment med fast storlek som inte är en integrerad multipel av en system-DMA-styrenhets cachestorlek. Om den här drivrutinen inte anropar FlushAdapterBuffers i slutet av varje enhetsöverföring kan den inte vara säker på när varje byte som drivrutinen faktiskt begärde kommer att överföras.

Drivrutinen för en bus-master DMA-enhet bör också anropa FlushAdapterBuffers i slutet av varje överföringsåtgärd för att se till att alla data har överförts till systemminnet eller ut till enheten.

FlushAdapterBuffers returnerar ett booleskt värde som anger om den begärda tömningsåtgärden lyckades. En drivrutin kan använda det här värdet för att avgöra hur du anger I/O-statusblocket när du slutför en IRP för en DMA-läs- eller skrivåtgärd.