Я очень удивлен, никто не ответил на этот вопрос, так что здесь мы идем на конкретный ответ, не Linux (у меня есть недостаточное знание самой, чтобы быть более конкретным Linux ядра) ...
Cache слежка просто сообщает контроллеру DMA отправлять запросы на отмену кэширования для всех ЦП для памяти, в которую помещается DMAed. Это, очевидно, добавляет нагрузку на когерентную шину кэша, и она особенно сильно масштабируется с дополнительными процессорами, так как не все процессоры будут иметь одно соединение хопа с контроллером DMA, выдающим snoop. Поэтому простой ответ на «когда безопасно отключить отслеживание кеша» - это когда память, которая находится в DMAed, либо не существует в любом кэше ЦП, либо ее строки кэша помечены как недействительные. Другими словами, любая попытка чтения из области DMAed будет всегда приведет к чтению из основной памяти.
Итак, как вы гарантируете, что чтения из области DMAed всегда будут поступать в основную память?
Назад в день, прежде чем мы имели орнаментальные функции, такие как DMA кэш Snooping, что мы привыкли делать было трубопроводному DMA памяти путем подачи его через ряд разбитых этапов следующим образом:
Этап 1: Добавить " грязной "области памяти DMA в« грязный и подлежащий очистке »список памяти DMA.
Этап 2: В следующий раз, когда устройство прерывает свежие данные DMA, выпустите асинхронный кеш центрального процессора за недействительность для сегментов DMA в списке «грязный и подлежащий очистке» для всех процессоров, которые могут обращаться к этим блокам (часто каждый процессор запускает собственные списки, состоящие из блоков локальной памяти). Переместите указанные сегменты в «чистый» список.
Этап 3: Следующее прерывание DMA (конечно, вы уверены, что этого не произойдет до того, как завершится предыдущее завершение кэша), возьмите новую область из «чистого» списка и сообщите устройству, что его следующий DMA должен идти в это. Перерабатывайте любые грязные блоки.
Этап 4: Повторите.
Насколько это больше работает, у него есть несколько основных преимуществ. Во-первых, вы можете привязать обработку DMA к одному CPU (обычно к первому CPU0) или одному узлу SMP, что означает, что только один процессор/узел должен беспокоиться о недействительности кэша.Во-вторых, вы даете подсистеме памяти гораздо больше возможностей скрывать задержки памяти для вас, распределяя операции со временем и расширяя нагрузку на шину когерентности кэша. Ключом к производительности, как правило, является попытка сделать любой DMA на процессоре как можно ближе к соответствующему контроллеру DMA, насколько это возможно, и в памяти как можно ближе к этому CPU.
Если вы всегда передайте новое DMAed в память в пространство пользователя и/или другие процессоры, просто добавьте только что приобретенную память в передней части асинхронного кэша, недействительного конвейера. Некоторые операционные системы (не уверенные в Linux) имеют оптимизированную подпрограмму для предопределенной нулевой памяти, поэтому ОС в основном занумевает память в фоновом режиме и поддерживает быстрый кеш-кеш - она будет платить вам за сохранение новых запросов на память ниже этой кешированной суммы, поскольку обнуление памяти очень медленный. Я не знаю о какой-либо платформе, созданной за последние десять лет, которая использует аппаратную перезагрузку памяти, поэтому вы должны предположить, что вся свежая память может содержать допустимые строки кеша, которые требуют недействительности.
Я ценю это только наполовину на ваш вопрос, но это лучше, чем ничего. Удачи!
Найл
Там было несколько LWN статей о DMA и когерентности кэша вы можете захотеть взглянуть вокруг на lwn.net – Spudd86
Вы измерили производительность получить вы получаете путь отключения кэша слежки , а не только от самой передачи, а от приложения в целом? Когерентность DMA настолько удобна и позволяет намного легче взаимодействовать с оборудованием, чтобы я тщательно измерил, прежде чем отключать его. –