文章目录
1、 cache一致性协议 MESI
这个很少会问
2、 DMA与cache的一致性
2.1 出现内存不一致的原因
CPU写内存的时候有两种方式:
-
- write through: CPU直接写内存,不经过cache。
-
- write back: CPU只写到cache中。cache的硬件使用LRU算法将cache里面的内容替换到内存。通常是这种方式。
DMA可以完成从内存到外设直接进行数据搬移。但DMA不能访问CPU的cache,CPU在读内存的时候,如果cache命中则只是在cache去读,而不是从内存读,写内存的时候,也可能实际上没有写到内存,而只是直接写到了cache。

这样一来,如果DMA从将数据从外设写到内存,CPU中cache中的数据(如果有的话)就是旧数据了,这时CPU在读内存的时候命中cache了,就是读到了旧数据;CPU写数据到内存时,如果只是先写到了cache,则内存里的数据就是旧数据了。这两种情况(两个方向)都存在cache一致性问题。例如,网卡发包的时候,CPU将数据写到cache,而网卡的DMA从内存里去读数据,就发送了错误的数据。

- write back: CPU只写到cache中。cache的硬件使用LRU算法将cache里面的内容替换到内存。通常是这种方式。
2.2 如何解决一致性问题
主要靠两类APIs:
2.2.1 一致性DMA缓存(Coherent DMA buffers)
DMA需要的内存由内核去申请,内核可能需要对这段内存重新做一遍映射,特点是映射的时候标记这些页是不带cache的,这个特性也是存放在页表里面的。
上面说“可能”需要重新做映射,如果内核在highmem映射区申请内存并将这个地址通过vmap映射到vmalloc区域,则需要修改相应页表项并将页面设置为非cache的,而如果内核从lowmem申请内存,我们知道这部分是已经线性映射好了,因此不需要修改页表,只需修改相应页表项为非cache即可。
相关的接口就是dma_alloc_coherent()和dma_free_coherent()。dma_alloc_coherent()会传一个device结构体指明给哪个设备申请一致性DMA内存,它会产生两个地址,一个是给CPU看的,一个是给DMA看的。CPU需要通过返回的虚拟地址来访问这段内存,才是非cache的。至于dma_alloc_coherent()的内部实现可以不关注,它是和体系结构如何实现非cache(如mips的

本文探讨了在DMA操作中如何处理CPU Cache一致性问题。介绍了MESI协议,并详细阐述了出现内存不一致的原因,主要是CPU的write back方式与DMA操作冲突。接着,文章解释了解决一致性问题的两种主要方法:一致性DMA缓存和流式DMA映射,包括相关API的使用,如dma_alloc_coherent()、dma_free_coherent()、dma_cache_sync()、dma_map_sg()等。最后提到了硬件支持的Cache Coherent interconnect技术,可以简化一致性管理。

6557

被折叠的 条评论
为什么被折叠?



