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