Linux DMA子系统【8】- DMA及cache一致性的学习心得 --dma_alloc_writecombine

编程知识 行业动态 更新时间:2024-06-13 00:19:09

文章目录

  • 前言
  • 拓展阅读
  • 一、先理解cache的作用
  • 二、Cache的一致性
  • 三、Cache与内存的数据“不一致性”错误
  • 四、地址总线,物理地址
    • 4.1 地址总线:
    • 4.2 数据总线
    • 4.3 物理地址
    • 4.4 虚拟地址
  • 五、一致性总结
  • 六、dma_alloc_writecombine
  • 总结


前言

拓展阅读

  1. 总线地址、物理_虚拟地址、BCM2835芯片手册知识
  2. framebuffer使用DMA分析DMA一致性

一、先理解cache的作用

CPU在访问内存时,首先判断所要访问的内容是否在Cache中,如果在,就称为“命中(hit)”,此时CPU直接从Cache中调用该内容;否则,就 称为“ 不命中”,CPU只好去内存中调用所需的子程序或指令了。CPU不但可以直接从Cache读出内容,也可以直接往其中写入内容。由于Cache的存取速 率相当快,使得CPU的利用率大大提高,进而使整个系统的性能得以提升。

二、Cache的一致性

Cache的一致性就是指Cache中的数据,与对应的内存中的数据是一致的。

三、Cache与内存的数据“不一致性”错误

原因:
DMA是直接操作总线地址的,这里先当作物理地址来看待吧(系统总线地址和物理地址只是观察内存的角度不同)。如果cache缓存的内存区域不包括DMA分配到的区域,那么就没有一致性的问题。

  • 但是如果cache缓存包括DMA目的地址的话,会出现什么什么问题呢?
    问题出在,经过DMA操作cache缓存对应的内存数据已经被修改了,而CPU本身不知道(DMA传输是不通过CPU的),它仍然认为cache中的数据就是内存中的数据,以后访问Cache映射的内存时,它仍然使用旧的Cache数据。这样就发生Cache与内存的数据“不一致性”错误

四、地址总线,物理地址

相关文章可查看拓展阅读。

地址总线是从设备角度上看到的内存,物理地址是CPU的角度看到的未经过转换的内存(经过转换的是虚拟地址)

4.1 地址总线:

地址总线决定了cpu所能访问的最大内存空间的大小,是地址线数量之和
eg:若CPU的地址总线宽度是32位,那么CPU的寻址范围是4G(2的32次方位),所以最多支持4G内存.

4.2 数据总线

数据总线: 数据总线CPU与内存或其他器件之间的数据传送的通道。
CPU通过地址总线寻址,然后通过数据总线外部设备互换信息。
每条传输线一次只能传输1位二进制数据。eg: 8根数据线一次可传送一个8位二进制数据(即一个字节)

4.3 物理地址

物理地址是内存中的内存单元实际地址。物理地址就是内存中每个内存单元的编号。

4.4 虚拟地址

程序访问存储器所使用的==逻辑地址(基于算法的地址[软件层面的地址:假地址])称为虚拟地址

操作系统采用这种内存管理方法。
是防止程序对物理地址写数据造成一些不可必要的问题,比如知道了A进程的物理地址,那么向这个地址写入数据就会造成A进程出现问题,在虚拟内存中运行程序永远不知道自己处于内存中那一段的物理地址上!现在操作系统运行在保护模式下即便知道其他进程的物理地址也不允许向其写入!但是可以通过操作系统留下的后门函数获取该进程上的虚拟地址空间所有控制权限并写入指定数据

五、一致性总结

由上面可以看出,DMA如果使用cache,那么一定要考虑cache的一致性。解决DMA导致的一致性的方法最简单的就是禁止DMA目标地址范围内的cache功能。但是这样就会牺牲性能。

因此在DMA是否使用cache的问题上,可以根据DMA缓冲区期望保留的的时间长短来决策。DAM的映射就分为:一致性DMA映射流式DMA映射

一致性DMA映射申请的缓存区能够使用cache,并且保持cache一致性。一致性映射具有很长的生命周期,在这段时间内占用的映射寄存器,即使不使用也不会释放。生命周期为该驱动的生命周期

流式DMA映射实现比较复杂,因为没具体了解,就不说明了。只知道种方式的生命周期比较短,而且禁用cache。一些硬件对流式映射有优化。建立流式DMA映射,需要告诉内核数据的流动方向。

六、dma_alloc_writecombine

因为LCD随时都在使用,因此在Frame buffer驱动中,使用一致性DMA映射
上面的代码中用到 dma_alloc_writecombine函数,另外还有一个一致性DMA映射函数dma_alloc_coherent

/*
* Allocate DMA-coherent memory space and return both the kernel remapped
* virtual and bus address for that space.
*/
void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
{
	void *memory;
	if (dma_alloc_from_coherent(dev, size, handle, &memory))
		return memory;
	if (arch_is_coherent()) 
	{
		void *virt;
		virt = kmalloc(size, gfp);
		if (!virt)
			return NULL;
		*handle = virt_to_dma(dev, virt);
		return virt;
	}
	return __dma_alloc(dev, size, handle, gfp,
	pgprot_noncached(pgprot_kernel));
}
/*
* Allocate a writecombining region, in much the same way as
* dma_alloc_coherent above.
*/
void *
dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
{
	return __dma_alloc(dev, size, handle, gfp,
	pgprot_writecombine(pgprot_kernel));
}
#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) &~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) &~L_PTE_CACHEABLE)
  • dma_alloc_coherent 在 arm 平台上会禁止页表项中的 C (Cacheable) 域以及 B (Bufferable)域。而 dma_alloc_writecombine 只禁止 C (Cacheable) 域.

  • C 代表是否使用高速缓冲存储器, 而 B 代表是否使用写缓冲区。

这样,dma_alloc_writecombine 分配出来的内存不使用缓存,但是会使用写缓冲区。而 dma_alloc_coherent 则二者都不使用。

C B 位的具体含义

  • 0 0 无cache,无写缓冲;任何对memory的读写都反映到总线上。对 memory 的操作过程中CPU需要等待。
  • 0 1 无cache,有写缓冲;读操作直接反映到总线上;写操作,CPU将数据写入到写缓冲后继续运行,由写缓冲进行写回操作。
  • 1 0 有cache,写通模式;读操作首先考虑cache hit;写操作时直接将数据写入写缓冲,如果同时出现cache hit,那么也更新cache。
  • 1 1 有cache,写回模式;读操作首先考虑cache hit;写操作也首先考虑cache hit。
    这样,两者的区别就很清楚了。

A = dma_alloc_writecombine(struct device *dev, size_t size,dma_addr_t *handle, gfp_t gfp);

含义:
A : 内存的虚拟起始地址,在内核要用此地址来操作所分配的内存
dev : 可以平台初始化里指定,主要是用到dma_mask之类参数,可参考framebuffer
size : 实际分配大小,传入dma_map_size即可
handle: 返回的内存物理地址,dma就可以用。


总结

更多推荐

Linux DMA子系统【8】- DMA及cache一致性的学习心得 --dma_alloc_writecombine

本文发布于:2023-03-27 22:18:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/ff5fb7d645653fdc650b65ca6161fb67.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:子系统   学习心得   DMA   Linux   dma_alloc_writecombine

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!