本文介绍: 首先需要明确DMA-BUF,Dma buffer,ION和DMA-BUF Heap是不同的概念。在Android 多媒体系统中为了减少因不同进程之间内存多次拷贝而产生的不必要的开销,最直接的想法是希望跟硬件设备进行交互应用能有一个内存能跟设备驱动程序共享数据,理想情况是这个buffer能够直接是通过memory map得到,并且是物理连续的,这样就能让DMA直接读写这块buffer,减少CPU或者外设来访问内存的开销。

一、DMA-BUF等概念介绍

首先需要明确DMA-BUF,Dma buffer,ION和DMA-BUF Heap是不同的概念

在Android 多媒体系统中为了减少因不同进程之间内存的多次拷贝而产生的不必要的开销,最直接的想法是希望跟硬件设备进行交互应用能有一个内存能跟设备驱动程序共享数据,理想情况是这个buffer能够直接是通过memory map得到,并且是物理连续的,这样就能让DMA直接读写这块buffer,减少CPU或者外设来访问内存的开销。

为此kernel引入了DMA-BUF这个框架(或者说是子系统),来解决CPU和各种不同外设驱动之间buffer共享问题

DMA-BUF框架实现一个dmabuf文件系统(filesystem),这个文件系统直接通过调用挂载接口挂载到了内核没有提供挂载节点),每个dmabuf实例,会在文件系统创建inodefile,并将fd返回调用者调用者通过对fileioctrlmap操作,来操作dmabuffer

也就是说为了实现buffer共享,DMA-BUF将bufferfile关联起来,通过file来间接的引用共享buffer, 即 dmabuf 既是块物理 buffer,又是个 linux file。buffer 是内容,file 是媒介,只有通过 file 这个媒介才能实现同一 buffer 在不同驱动之间的流转。

代码位置

common/driver/dma-buf/
//或
/kernel/msm-5.4/drivers/dma-buf/dma-buf.c

DMA-BUF

如上图所示,在DMA-BUF框架中有两个很重要的概念一个exporter,另一个importer。

dma buffer 本身由 DMA-BUF exporter 创建,DMA-BUF exporter一个驱动程序,它可以分配特定类型的内存,而且还为 kerneluser spacedevice 提供了多种回调函数处理 buffer 的 map 和 unmap 问题,所以exporter相当于一个buffer的生产者或者说是提供者。

而DMA-BUF importer则对应dma buffer的使用者比如上层应用,而因为dma buffer是一种共享内存,所以同一个buffer的importer可以多个二者特性说明

  1. exporter:

  2. importer:

二、基于DMA-BUF框架的内存分配

过去几年中,Android系统里面已经使用过多种DMA buffer分配方案:首先是PMEM,然后被Android 系统下专用于分配 Graphic Buffer 的内存分配器ION所替换

ION 是基于 DMA-BUF 实现的,可以多个设备之间实现 buffer 共享,它的代码一直存放在 staging 目录下,不过再过几年可能就不复存在了,因为ION自从2012年开始商用以来也存在着不少问题

随后John Stultz发布了一个patch set,实现了DMA-BUF heap,是ION的一个演进版本,在之前的 Android 12 中,GKI 2.0 将 ION 分配器已经被替换为了 DMA-BUF Heap,因为DMA-BUF HEAP的分配器具有具有稳定的 ABI和安全性,也更标准化。

综上需要明确的是,不管是ION还是DMA-BUF heap都是基于DMA-BUF框架的一种分配器allocator,也就是说ION和DMA-BUF heap是上面DMA-BUF中提到的exporter驱动。

  1. ION分配器:
    ION是基于DMA-BUF框架实现的一种内存分配器,在多媒体部分中使用的最多,从 Camera 到 Display,从 Mediaserver 到 Surfaceflinger,都会利用 ION 进行内存分配管理

ION提供了多个memory pool,称为“heaps”。它们有不同的属性例如有的是物理连续的,有的不是。这些heap包括“systemheap用来vmalloc_user()分配;“system_contig”h eap,是用kzalloc()分配的。还有“carveoutheap,是在启动阶段额外划分出来的物理连续区域应用程序可以用一些user space的API来对这些heap分配、释放、共享内存。

ION的特点是它可以用户空间进程之间或者内核空间模块之间进行内存共享,且这种共享方式是零拷贝的。

代码位置

//本文的许多结构都是以内核4.14(kernel-4.14)为例,因为在内核5(kernel-5.10)以后的版本中,ION逐渐被弃用,许多代码已经不太相同
common/drivers/staging/android/ion/
kernel-4.14/drivers/staging/android/ion/
//或
/kernel/msm-5.4/drivers/staging/android/ion/
kernel-5.10/drivers/staging/android/ion/

ION

ION 是在各种 heaps 上分配内存,通过 ion_buffer 来描述所分配的内存。

每个heap中分配了若干个buffer,不同的client是通过文件描述符fd来实现内存共享的。

ION是在各种heaps上分配内存,其中定义了四种不同的heap,实现不同的内存分配策略

  1. DMA-BUF heaps分配器:
    DMA-BUF heaps也是一种基于DMA-BUF框架实现的内存分配器,是一种取代ION分配的方式

ION开发的时候,kernel也有一个DMA buffer sharing (DMA-BUF)的API在同时进行开发,此外还有contiguous memory allocator (CMA)。所以功能上有些重复。此外,ION起初是在32-bit ARM处理器上为Android开发的,所以用了一些ARM特有的kernel API。这些都是合入linux mainline的阻碍。而这个新的基于DMA-BUF heap的patch就对ION的内部实现做了彻底的重构,使用CMA来基于某个特殊内存区域实现物理连续heap,也不再使用ARM特有的函数了。patch set还带了一个selftest展示了API是如何使用的。

DMA-BUF Heap的代码主要位置

common/driver/dma-buf/heaps/
//主要文件
common/include/linux/dma-heap.h
common/include/uapi/linux/dma-heap.h
common/driver/dma-buf/dma-heap.c            //或/msm-kernel/drivers/dma-buf/dma-heap.c
common/drivers/dma-buf/heaps/system_heap.c
common/drivers/dma-buf/heaps/cma_heap.c

三、ION heap和 DMA-BUF heap的区别

  1. 分配方式不同
  1. DMA-BUF heap可通过不同的字符设备名控制访问权限,更安全
  1. DMA-BUF heap不支持堆专用标志,所以更容易对外提供统一接口,利于标准化
  • 对于ION heap来说,会通过专用标志来实现不同的内存分配策略

如ION 在 SYSTEM_HEAP 上分配内存时,使用ION_HEAP_SYSTEM来分配,而对于是否分配带 cache 的 buffer,则是通过传入 ION_FLAG_CACHED 标志位来实现的。(也就是说可以支持同一个heap中传入vendor私有的heap flags来实现不同的分配方式

//ION中系统堆中的缓存分配
//libion
ion_alloc_fd(ionfd, size, 0, ION_HEAP_SYSTEM, ION_FLAG_CACHED, &fd)

因为是专用标志,也就是私有化,不同的vendor厂商实现不同不容易统一。

  • 对于 DMA-BUF heap来说,则不支持堆的专用标志。每种不同的分配都是在不同的堆中完成的。

例如,对于在ION中system heap的cached和uncached两种分配方式在DMA-BUF heap中则是会生成两个独立的heap: /dev/dma_heap/system 和 /dev/dma_heap/system_uncached

//DMA-BUF中系统堆中的缓存分配
//libdmabufheap
allocator->Alloc("system", size)

对于HEAP堆类型简单说明
  • CMA HEAP(物理连续 buffer)

  • SYSTEM HEAP(物理非连续 buffer)
    SYSTEM HEAP 默认支持带 Cached 的 buffer,只有 CPU 需要参与访问的 buffer 才需要cached,这样可以加快 CPU 的访问速度,但是在 CPU 和 DMA 设备之间共享内存时,需要来回刷 Cache,这会增加系统开销。

  • SYSTEM-UNCACHED HEAP(应用程序申请不带 cache 的 buffer)
    不带 cached 的 buffer 则通常只用于 DMA 设备之间的 buffer 共享,因此省去了 Cache 同步所带来的额外开销,极大的提高了 DMA 设备访问 buffer 的效率。


参考

dma-buf 由浅入深(八) —— ION 简化版

Buffer Sharing and Synchronization

Camera Buffer Management

dma-heap: Add a system-uncached heap

DMA_HEAP源码

原文地址:https://blog.csdn.net/u011795345/article/details/129306630

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_20314.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注