缓存 - 刷新和无效操作

kum*_*mar 17 hardware caching driver device-driver dma

我对缓存同步操作有一些疑问.

无效:在cpu尝试读取设备更新的部分内存之前,需要使相应的内存无效.

刷新:在设备读取CPU更新的部分内存之前,CPU必须刷新(写回也是正确的?)从缓存到内存的内容,以便设备从内存中读取更新内容的内容.

如果不执行刷新,则它可以读取存储器中存在的垃圾数据,因为存储器仍未使用写入高速缓存的内容进行更新.

请确认我的上述理解是否正确?

您想什么时候将flush和invalidate结合起来?我听说在使用设备控制描述符时,我们需要通过组合flush和invalidate进行同步.为什么这样?

我们是否需要遵循像flush这样的序列然后无效?

是否有一个场景,其中有效的后续执行无效?

BCr*_*ran 26

Flush会将缓存的内容写回主内存,而invalidate会将缓存行标记为无效,以便将来的读取转到主内存.

我认为如果设备正在更新内存块,你将组合flush和invalidate:flush将确保设备具有最新内容,而invalidate将确保当设备完成时CPU将读取新内容从记忆里.

  • 为清楚起见,这主要是在初始化阶段进行的.初始化描述符在初始化阶段都被刷新(在内存中更新)和无效(因此下一次由CPU读取具有有用内容). (2认同)

use*_*812 5

请确认我的上述理解是否正确?

一般来说,你是完全正确的,但有些石头可能会导致绊倒。您没有指定硬件平台。如果我们讨论的不是带有 SRAM 的小型嵌入式控制器,请考虑以下因素。配备 MMU 的处理器支持普通 DDR 内存和驱动程序(硬件相关)内存的不同内存属性。最后一个是不可缓存的,因此不用担心刷新/失效。


你什么时候想结合使用flush和invalidate?我听说在使用设备控制描述符时,我们需要通过组合刷新和无效来进行同步。为什么这样?

由于标签中提到了 DMA,因此有几种情况(假设 HW 缓冲区是不可缓存的设备内存):

  1. DMA 将数据从 DDR 内存传输到 HW 缓冲区。
  2. DMA 将数据从 HW 缓冲区传输到 DDR(HW 接收到数据并希望使其可供 CPU 使用)
  3. DMA 从 DDR 传输到 DDR 的另一个区域。

  1. DDR 缓冲区应在 DMA 之前刷新。驱动程序缓冲区不可缓存,因此无需失效。
  2. DDR 缓冲区应在 DMA 传输之前或之后(详细信息请参见下文)无效NOTE,以防止 CPU 使用缓存中的“旧”数据。刷新 HW 缓冲区是多余的。
  3. 应刷新“源”缓冲区,应使“目标”缓冲区无效。因此,在传输之前,DMA 的有效数据位于内存中,并且在 DMA 完成其工作后,CPU 不会从缓存中获取“污垢”。


NOTE:很明显,“源”应该在 DMA 之前刷新。仍然存在何时失效的问题。从技术上讲,它是在 CPU 尝试访问“目标”数据之前,并且可能在 DMA 之前或之后(我们应该确保 DMA 已完成工作)。DMA后IRL 失效可能会导致问题。参考 虚拟地址的Flush/Invalidate范围;ARMv8;缓存;

正如您所看到的,该特定平台的无效应该在 DMA之前完成。另外,我还漫谈了 ARMv7 设备的 BSP 代码,发现建议在DMA 传输之前使目标缓冲区无效。
但这还不是全部。您可能希望在DMA 传输再次(没错,第二次)后使目标缓冲区无效。如果相关芯片具有预取功能,它可以在 DMA 工作时将数据取回到缓存。因此顺序可能是:第一次使预取无效后,再次将数据放入缓存 -> DMA 覆盖内存中的数据 -> 缓存具有与内存不同的数据,并且缓存被标记为具有有效数据。第二次无效将确保数据再次检索到缓存中,因此缓存和内存完成同步:)


我们是否需要遵循先刷新后无效的顺序?

假设源缓冲区和目标缓冲区不相互交叉,则不存在依赖性。你可以flush-invalidate或者invalidate-flush


是否存在先无效后刷新有用的场景?

不这么认为。