Кеш - операция сброса и недействительности
У меня есть некоторые вопросы по операциям синхронизации кеша.
Invalidate. Прежде чем процессор попытается прочитать часть памяти, обновленную устройством, соответствующая память должна быть недействительной.
Flush. Прежде чем устройство прочитает часть памяти, обновленную процессором, CPU должен сброситься (записать обратно также правильно?) содержимое из кеша в память, чтобы устройство считывало содержимое из памяти с обновленным содержимым.
Если флеш не выполняется, он может считывать нежелательные данные, присутствующие в памяти, поскольку память еще не обновляется содержимым, записанным в кеш.
Пожалуйста, подтвердите правильность моего понимания?
Когда вы хотите комбинировать как флеш, так и аннулировать? Я слышал, что, играя с дескрипторами управления устройством, нам нужно синхронизировать, объединяя флеш и недействительно. Почему так?
Нужно ли следовать последовательности, такой как flush, за которой следует invalidate?
Есть ли сценарий, в котором может быть полезен недействительный, за которым следует флеш?
Ответы
Ответ 1
Флеш записывает содержимое кеша в основную память, а недействительность делает отметки кэша недействительными, поэтому будущие чтения переходят в основную память.
Я думаю, что вы объединили бы flush и invalidate, если бы устройство обновляло блок памяти: флеш обеспечил бы, чтобы устройство имело самое последнее содержимое, а invalidate будет гарантировать, что когда устройство закончит чтение ЦП новое содержимое из памяти.
Ответ 2
Пожалуйста, подтвердите правильность моего понимания?
Как правило, вы совершенно правы, но есть камни, которые могут вызвать спотыкание. Вы не указали платформу HW. Если мы не говорим о небольших встроенных контроллерах, упакованных с SRAM, рассмотрим следующее.
Процессоры, оснащенные MMU, поддерживают различные атрибуты памяти для нормальной памяти DDR и памяти, связанной с драйвером (HW). Последний из них не кэшируемый, поэтому нет никаких опасений по поводу промывки/недействительности.
Когда вы хотите комбинировать как флеш, так и аннулировать? я слышал это при игре с дескрипторами управления устройством нам необходимо синхронизировать путем объединения флеша и недействительности. Почему так?
Так как DMA упоминается в тегах, существует несколько сценариев (предполагая, что HW-буфер является памятью, не подлежащей кэшированию):
- Передача данных DMA из памяти DDR в буфер HW.
- Передача данных DMA из буфера HW в DDR (данные HW получены и хотят сделать их доступными для CPU)
- Передача DMA из DDR в другой регион DDR.
- Буфер DDR должен быть покрашен перед DMA. Буфер драйвера не кэшируется, поэтому нет необходимости в аннулировании.
- DDR-буфер должен быть недействительным до или после (смотрите ниже
NOTE
ниже). Передача DMA для предотвращения использования процессором "старых" данных из кеша. Промывка буфера HW избыточна.
- Буфер источника должен быть сброшен, буфер "Целевой" должен быть недействительным. Таким образом, действительные данные хранятся в памяти для DMA перед передачей, а CPU не берет "грязь" из кэша после того, как DMA выполнил эту работу.
NOTE
: Очевидно, что перед DMAing "источник" должен быть покрашен. Еще есть вопрос, когда сделать недействительным. Технически это до того, как CPU попытается получить доступ к данным "Destination" и может быть до или после DMA (мы должны убедиться, что DMA закончил работу). IRL недействительный после DMAing может привести к возникновению проблемы. Ссылаться на
Flush/Invalidate range по виртуальному адресу; ARMv8; Кэш;
Как вы могли видеть, invalidate для этой конкретной платформы должно выполняться до DMAing. Кроме того, я искал th/код BSP для устройства ARMv7, я нашел рекомендацию недействить буфер назначения до передачи DMA.
Нужно ли следовать последовательности, такой как flush, за которой следует invalidate?
Предполагая, что буферы источника и получателя не пересекаются друг с другом, нет зависимостей. Вы могли бы flush-invalidate
или invalidate-flush
.
Есть ли сценарий, в котором может быть полезен недействительный, за которым следует флеш?
Не думай так.