Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
На некоторых платформах процессор и системный контроллер DMA (или адаптеры DMA с магистральным управлением) демонстрируют аномалии когерентности кеша. Следующие рекомендации позволяют драйверам, использующим интерфейс операций DMA версии 1 или 2 (см. DMA_OPERATIONS), поддерживать согласованное состояние кэша на всех поддерживаемых архитектурах процессора, включая архитектуры, не имеющие аппаратных средств для автоматического обеспечения когерентности кэша.
Примечание Рекомендации в этом разделе применяются только к драйверам, используюющим версии 1 и 2 интерфейса операций DMA. Драйверы, использующие версию 3 этого интерфейса, должны соответствовать другому набору рекомендаций. Дополнительные сведения см. в версии 3 интерфейса операций DMA .
Для поддержания целостности данных во время операций DMA драйверы нижнего уровня должны соответствовать этим рекомендациям
Вызовите KeFlushIoBuffers перед началом операции передачи, чтобы обеспечить согласованность между данными, которые могут кэшироваться в процессоре и данных в памяти.
Если драйвер вызывает AllocateCommonBuffer с параметром CacheEnabled, установленным в значение TRUE, драйвер должен вызвать KeFlushIoBuffers перед началом операции передачи данных в буфер или из него.
Вызовите FlushAdapterBuffers в конце каждой операции передачи устройства для надежной записи всех оставшихся байт в буферах системного DMA-контроллера в память или в подчиненное устройство.
Или вызовите FlushAdapterBuffers в конце каждой операции передачи для заданного IRP, чтобы убедиться, что все данные считываются в системную память или записаны на устройство DMA главного шины.
На приведенном ниже рисунке показано, почему важно очистить кэш процессора перед операцией чтения или записи с помощью DMA, если процессор узла и контроллер DMA не поддерживают параллелизм кэша.
Асинхронная операция чтения или записи DMA обращается к данным в памяти, а не в кэше процессора. Если этот кэш не был удален путем вызова KeFlushIoBuffers непосредственно перед чтением, данные, передаваемые в системную память операцией DMA, могут быть перезаписаны с устаревшими данными, если кэш процессора сбрасывается позже. Если кэш процессора не был удален путем вызова KeFlushIoBuffers непосредственно перед записью, данные в этом кэше могут быть более up-to-date, чем копия в памяти.
KeFlushIoBuffers ничего не делает, если процессор и контроллер DMA можно использовать для поддержания когерентности кэша, поэтому вызовы этой подпрограммы поддержки практически не имеют накладных расходов на такой платформе.
Как показано на предыдущем рисунке, контроллеры DMA, представленные объектами адаптера, могут иметь внутренние буферы. Такой контроллер DMA может передавать кэшированные данные в блоках фиксированного размера, обычно восемь или более байтов одновременно. Кроме того, эти контроллеры DMA могут ждать, пока их внутренние буферы будут заполнены перед каждой операцией передачи.
Рассмотрим случай драйвера низкого уровня, использующего подчиненный DMA для чтения данных в блоках переменного размера или в блоках фиксированного размера, которые не являются целыми кратными размеру кэша контроллера DMA системы. Если этот драйвер не вызывает FlushAdapterBuffers в конце каждой передачи устройства, он не может быть уверен, когда каждый байт, запрошенный драйвером, фактически будет передан.
Драйвер устройства DMA главного шины также должен вызывать FlushAdapterBuffers в конце каждой операции передачи для IRP, чтобы убедиться, что все данные были переданы в системную память или на устройство.
FlushAdapterBuffers возвращает логическое значение, указывающее, выполнена ли запрошенная операция очистки успешно. Драйвер может использовать это значение, чтобы определить, как задать блок состояния ввода-вывода при завершении IRP с операцией чтения или записи с помощью DMA.