什么是DMA和CPU访问内存的一致性问题

问题1:当CPU访问某一块内存A时,CPU访问的时候,如果cache没有命中,则会将A这块内存里 面的数据刷新到cache中,当CPU再次读取A内存的数据发现cache已经命中,直接在cache 中取数据即可,不必再去更新内存的数据。这个时候如果有一个DMA的操作,去操作了A这 块内存,但是CPU不知道这块内存的数据已经更新,当CPU再次读取A块内存的数据时,发 现cache命中了,还是会直接读取cache的数据,而不更新内存的数据,这个时候就造成了 cache和内存里面数据不一致的情况。

问题2:CPU写一片内存A,但是CPU写这块内存的时候,其实是先写在cache上,在适当的时候再 写回内存中。这个时候,我们想要写一些数据到内存,然后再通过DMA操作把这块数据搬 到设备FIFO上去,如果我们想要写的数据没有从cache中write back回内存,这个时候就会出现 我要给用户发送的数据和用户收到的数据不一致的问题。

上面两个问题会带来两个问题:一种是别人给我发数据,我读取到的数据不对。另一种是我要发给别人数据,我觉得我已经写到内存中,然后通过DMA发给了对方,但是对方读取的数据不对。

如何解决一致性问题

两种解决方法:

  • 一致性DMA映射(Consistent DMA mappings )

CPU和DMA controller在发起对DMA buffer的并行访问的时候不需要考虑cache的影响,CPU和DMA controller都可以看到对方对DMA buffer的更新。

dma_alloc_coherent()

dma_alloc_writecombine()

dma_pool_alloc()

  • 流式DMA映射(streaming DMA mapping)

这种方式在map的时候要指定一个参数,来指明数据的方向是从外设到内存还是从内存到外设:

从内存到外设:CPU会做cache的flush操作,将cache中新的数据刷到内存。

从外设到内存:CPU将cache置无效,这样CPU读的时候不命中,就会从内存去读新的数据。

map单个的dma buffer: dma_map_single()

map多个形成scatterlist的dma buffer: dma_map_sg()

下篇文章一起看下这两类接口的用法和实现。

DMA和CPU访问内存的一致性问题

相关文章:

  • 2021-10-01
  • 2022-12-23
  • 2022-01-03
  • 2021-11-24
  • 2021-07-01
  • 2022-12-23
  • 2022-12-23
  • 2022-03-03
猜你喜欢
  • 2021-09-12
  • 2022-12-23
  • 2021-10-01
  • 2022-12-23
  • 2021-09-02
  • 2021-07-09
  • 2021-10-20
相关资源
相似解决方案