早在2011年12月,LWN审查了linux-next目录中的Android内核补丁列表。这些驱动程序的合并,其中一个是名为PMEM的内存分配器,为了使主线内核发行版有一天可以引导一个Android用户空间。从那时起,很明显 PMEM被视为过时的, 并将由ION内存管理器替换。ION是Google在Android 4.0 ICS(冰淇淋三明治)版本中引入的一种通用内存管理器,旨在解决跨不同Android设备的内存管理碎片化问题。至少有三个(可能更多)类似PMEM的接口。在使用NVIDIA Tegra的Android设备上,有“ NVMAP”; 在使用TI OMAP的Android设备上,存在“ CMEM”;在使用Qualcomm MSM的Android设备上,存在“ PMEM”。所有这三个SoC供应商都在过渡到ION。

本文介绍了ION,总结了它与用户空间和内核空间驱动程序的接口。ION除了是内存池管理器之外,还使它的客户端可以共享缓冲区,因此与Linaro(DMABUF)的DMA缓冲区共享框架具有相同的基础。本文将以两种缓冲区共享方案的比较结束。

 

ION heaps

像其类似PMEM的前辈一样,ION管理一个或多个内存池,其中一些在启动时被保留以应对碎片或满足特殊的硬件需求。GPU,display controller和camera是可能具有特殊内存要求的一些硬件模块。ION将其内存池显示为ION heaps。每种类型的Android设备都可以根据设备的内存需求配置不同的ION heaps集。ION heaps的提供者/server必须实现以下一组回调函数:

struct ion_heap_ops {
	int (*allocate) (struct ion_heap *heap,
			 struct ion_buffer *buffer, unsigned long len,
			 unsigned long align, unsigned long flags);
	void (*free) (struct ion_buffer *buffer);
	int (*phys) (struct ion_heap *heap, struct ion_buffer *buffer,
		     ion_phys_addr_t *addr, size_t *len);
	struct scatterlist *(*map_dma) (struct ion_heap *heap,
			 struct ion_buffer *buffer);
	void (*unmap_dma) (struct ion_heap *heap, 
	         struct ion_buffer *buffer);
	void * (*map_kernel) (struct ion_heap *heap, 
	         struct ion_buffer *buffer);
	void (*unmap_kernel) (struct ion_heap *heap, 
	         struct ion_buffer *buffer);
	int (*map_user) (struct ion_heap *heap, struct ion_buffer *buffer,
			 struct vm_area_struct *vma);
   };

简要地说,allocate()和free()从heap中获取或释放ion_buffer对象。调用phys()将返回缓冲区/buffer的物理地址和长度,但仅适用于物理上相邻的缓冲区。如果heap不提供物理上连续的缓冲区,则不必提供此回调。这里ion_phys_addr_t 是unsigned long的typedef ,有朝一日将被在include/linux/types.h中phys_addr_t取代 。map_dma()和unmap_dma()回调函数导致缓冲区为DMA准备(或未准备)。map_kernel()和 unmap_kernel()回调将物理内存映射(或取消映射)到内核虚拟地址空间。调用map_user()会将内存映射到用户空间。没有unmap_user(),因为映射在用户空间中表示为文件描述符fd。该文件描述符的关闭将导致内存从调用进程中取消映射。

---实际上,目前的ops更加简单:

struct ion_heap_ops {
	int (*allocate)(struct ion_heap *heap,
			struct ion_buffer *buffer, unsigned long len,
			unsigned long flags);
	void (*free)(struct ion_buffer *buffer);
	int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan);
	long (*get_pool_size)(struct ion_heap *heap);
};

commit 8eb89f277ee332b7fc02d808fc7d565ac6f0a828
Author: Sandeep Patil <sspatil@google.com>
Date:   Sun Sep 1 23:02:37 2019 -0700

    ANDROID: staging: ion: Remove unnecessary ion heap ops
    
    The heap operations are redundant now that we have default
    dma_buf operations. So, remove them.
    
    Bug: 133508579
    Bug: 140290587
    Test: ion-unit-tests
    
    Change-Id: I8f87c22896e128f48ed222421cabc23ab238ff69
    Signed-off-by: Sandeep Patil <sspatil@google.com>

 

默认的ION驱动程序(可以从此处克隆)提供三个heaps,如下所示:

ION_HEAP_TYPE_SYSTEM:        memory allocated via vmalloc_user().
   ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kzalloc.
   ION_HEAP_TYPE_CARVEOUT:	carveout memory is physically contiguous and set aside at boot.

开发人员可以选择添加更多的ION-heap。例如, 提交此NVIDIA补丁程序是为了为配备IOMMU的硬件模块添加ION_HEAP_TYPE_IOMMU。

---目前我看到的新的type类型

/**
 * enum ion_heap_types - list of all possible types of heaps
 * @ION_HEAP_TYPE_SYSTEM:	 memory allocated via vmalloc
 * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc
 * @ION_HEAP_TYPE_CARVEOUT:	 memory allocated from a prereserved
 * 				 carveout heap, allocations are physically
 * 				 contiguous
 * @ION_HEAP_TYPE_DMA:		 memory allocated via DMA API
 * @ION_NUM_HEAPS:		 helper for iterating over heaps, a bit mask
 * 				 is used to identify the heaps, so only 32
 * 				 total heap types are supported
 */
enum ion_heap_type {
	ION_HEAP_TYPE_SYSTEM,
	ION_HEAP_TYPE_SYSTEM_CONTIG,
	ION_HEAP_TYPE_CARVEOUT,
	ION_HEAP_TYPE_CHUNK,
	ION_HEAP_TYPE_DMA,
	ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always
				 are at the end of this enum */
	ION_NUM_HEAPS = 16,
};

Using ION from user space

通常,用户空间设备使用自己的库函数调用ion分配大的连续媒体缓冲区。例如,静态相机库分配要由相机设备使用的capture buffer。一旦缓冲区被视频数据完全填充,库可以将缓冲区传递给由JPEG编码器硬件块处理的内核。

用户空间C/C++程序必须被授予访问/dev/ion设备节点的权限,才能从ION中分配内存。调用 open(“/dev/ion”,O_RDONLY)返回一个文件描述符作为代表ION客户端的句柄。可以在O_RDONLY打开的情况下分配可写内存。每个用户进程最多只能有一个客户端。要分配缓冲区,客户端需要填写此数据结构中除handle字段以外的所有字段:

struct ion_allocation_data {
        size_t len;
        size_t align;
        unsigned int flags;
        struct ion_handle *handle;
   }

handle字段是输出参数,而前三个字段指定长度,对齐和flags作为输入参数。flags字段是一个位掩码,指示要从中分配的一个或多个ION-heap,并根据在引导期间调用ion_device_add_heap()首次添加的ION-heap来排序回调。在默认实现中,ION_HEAP_TYPE_CARVEOUT被添加到ION_HEAP_TYPE_CONTIG之前。ION_HEAP_TYPE_CONTIG | ION_HEAP_TYPE_CARVEOUT的标志表明了从ION_HEAP_TYPE_CARVEOUT分配并回调到ION_HEAP_TYPE_CONTIG的意图。

---新的结构体,已经把:

/**
 * struct ion_allocation_data - metadata passed from userspace for allocations
 * @len:		size of the allocation
 * @heap_id_mask:	mask of heap ids to allocate from
 * @flags:		flags passed to heap
 * @handle:		pointer that will be populated with a cookie to use to
 *			refer to this allocation
 *
 * Provided by userspace as an argument to the ioctl
 */
struct ion_allocation_data {
	__u64 len;
	__u32 heap_id_mask;
	__u32 flags;
	__u32 fd;
	__u32 unused;
};

 重要的变化,之前返回的是handle,现在是fd;不需要再传align了。

用户端分配缓冲区

1.用户空间客户端使用ioctl()系统调用接口与ION进行交互。为了分配缓冲区,客户端进行以下调用:

int ioctl(int client_fd, ION_IOC_ALLOC, struct ion_allocation_data *allocation_data)

2.该调用返回由ion_handle表示的缓冲区,该缓冲区不是CPU可访问的缓冲区指针。该句柄只能用于获取文件描述符以进行缓冲区共享,如下所示:

int ioctl(int client_fd, ION_IOC_SHARE, struct ion_fd_data *fd_data);

这里client_fd是对应于/dev/ion的文件描述符,fd_data是一个具有输入句柄字段和输出fd字段的数据结构,定义如下:

struct ion_fd_data {
        struct ion_handle *handle;
        int fd;
   }

fd字段是一个文件描述符,它可以被传递IPC来进行共享。在Android设备上,可以使用BINDER IPC机制将fd发送到另一个进程进行共享。要获取共享缓冲区,第二个用户进程必须首先通过open(“ /dev/ion”,O_RDONLY)系统调用获取客户端句柄。ION通过进程的PID(特别是进程中作为“组长”的线程的PID)跟踪其用户空间客户端。在同一进程中重复 open(“ /dev/ion”,O_RDONLY)调用将返回与内核中相同客户端结构相对应的另一个文件描述符。

3.要释放缓冲区,第二个客户端需要通过调用munmap()来撤消mmap()的影响,而第一个客户端需要关闭通过ION_IOC_SHARE获得的文件描述符,并按如下方式调用ION_IOC_FREE:

int ioctl(int client_fd, ION_IOC_FREE, struct ion_handle_data *handle_data);

这里ion_handle_data持有句柄,如下所示:

struct ion_handle_data {
	     struct ion_handle *handle;
     }

ION_IOC_FREE命令导致句柄的引用计数器减1。当这个引用计数器达到0时,ion_handle对象被销毁,受影响的ION簿记数据结构被更新。

最新ion目前用法是:

  • open /dev/ion
  • ioctl ION_IOC_ALLOC
  • mmap

---那如果是display

  • ioctl DRM_IOCTL_PRIME_FD_TO_HANDLE
  • drmModeAddFB
  • fb_id to plane

============================== ion_client以及ion_handle相关已经在2017年被完全移除,dmabuf冉冉升起

commit 15c6098cfec543687164a05faeb859f8e4f7480b
Author: Laura Abbott <labbott@redhat.com>
Date:   Tue Apr 18 11:27:12 2017 -0700

    staging: android: ion: Remove ion_handle and ion_client
    
    ion_handle was introduced as an abstraction to represent a reference to
    a buffer via an ion_client. As frameworks outside of Ion evolved, the dmabuf
    emerged as the preferred standard for use in the kernel. This has made
    the ion_handle an unnecessary abstraction and prone to race
    conditions. ion_client is also now only used internally. We have enough
    mechanisms for race conditions and leaks already so just drop ion_handle
    and ion_client. This also includes ripping out most of the debugfs
    infrastructure since much of that was tied to clients and handles.
    The debugfs infrastructure was prone to give confusing data (orphaned
    allocations) so it can be replaced with something better if people
    actually want it.
    
    Signed-off-by: Laura Abbott <labbott@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Sharing ION buffers in the kernel

用户进程也可以与内核驱动程序共享ION缓冲区;在内核中,ION支持多个客户端,每个使用ION功能的驱动程序一个。内核驱动程序调用以下函数以获得ION客户端句柄:

struct ion_client *ion_client_create(struct ion_device *dev, 
                   unsigned int heap_mask, const char *debug_name)

第一个参数dev是与/dev/ion关联的全局ION设备 ;尚不清楚为什么需要全局设备以及为什么必须将其作为参数传递。第二个参数 heap_mask以与ion_allocation_data相同的方式选择一个或多个ION堆。flag部分在上一节中进行了介绍。对于涉及多媒体中间件的智能手机用例,用户进程通常从ION分配缓冲区,使用ION_IOC_SHARE命令获得文件描述符,然后将文件描述符传递给内核驱动程序。内核驱动程序调用 ion_import_fd(),它将文件描述符转换为ion_handle 对象,如下所示:

struct ion_handle * ion_import_fd(struct ion_client * client,int fd_from_user);

ion_handle对象是驱动程序对共享缓冲区的客户端本地引用。ion_import_fd()调用查找缓冲区的物理地址,以查看客户端之前是否获得了同一个缓冲区的句柄,如果获得了,这个调用只会增加现有句柄的引用计数器。

某些硬件块只能在具有物理地址的物理连续缓冲区上运行,因此受影响的驱动程序需要通过以下调用将ion_handle转换为物理缓冲区:

int ion_phys(struct ion_client * client,struct ion_handle * handle,
	       ion_phys_addr_t * addr,size_t * len)

不用说,如果缓冲区在物理上不连续,则此调用将失败。

当处理来自client的调用时,ION总是验证输入文件描述符、客户机和handle参数。例如,在导入文件描述符时,ION确保文件描述符确实由ION_IOC_SHARE 命令创建。当调用ion_phys()时,ION会验证缓冲区句柄是否属于客户端允许访问的句柄列表,如果该句柄不在列表中,则返回错误。这种验证机制降低了意外访问和无意资源泄漏的可能性。

ION通过debugfs提供调试可见性。它将调试信息组织在/sys/kernel/debug/ion下,并将簿记信息保存在与由符号名或pid标识的堆和客户端相关联的存储文件中。

Comparing ION and DMABUF

ION和DMABUF有一些共同的概念。dma_buf概念类似于ion_buffer,而dma_buf_attachment的作用类似于ion_handle。ION和DMABUF都使用匿名文件描述符作为对象,可以传递这些对象来提供对共享缓冲区的引用计数访问。另一方面,ION专注于以一种可以共享和跟踪的方式分配内存并从已配置的内存池中释放内存,而DMABUF更侧重于以一种与非arm架构上的缓冲区共享解决方案一致的方式导入、导出和同步。

下表介绍了ION和DMABUF之间的功能比较:

Feature

ION

DMABUF

Memory Manager Role

ION replaces PMEM as the manager of provisioned memory pools. The list of ION heaps can be extended per device.

ION取代PMEM作为所分配内存池的管理器。每个设备的ION堆列表可以扩展。

DMABUF is a buffer sharing framework, designed to integrate with the memory allocators in DMA mapping frameworks, like the work-in-progress DMA-contiguous allocator, also known as the Contiguous Memory Allocator (CMA). DMABUF exporters have the option to implement custom allocators.

DMABUF是一个缓冲区共享框架,旨在与DMAmapping框架中的内存分配器集成,如正在工作的DMA连续分配器,也称为连续内存分配器(CMA)。DMABUF出口商可以选择实现自定义分配器。

User Space Access Control

ION offers the /dev/ion interface for user-space programs to allocate and share buffers. Any user program with ION access can cripple the system by depleting the ION heaps. Android checks user and group IDs to block unauthorized access to ION heaps.

ION为用户空间程序提供了/dev/ion接口来分配和共享缓冲区。任何具有ION访问权限的用户程序都可以通过消耗ION堆来削弱系统。Android检查用户和组id,以阻止对ION堆的未授权访问。

DMABUF offers only kernel APIs. Access control is a function of the permissions on the devices using the DMABUF feature.

DMABUF只提供内核api。访问控制是使用DMABUF特性的设备上的权限的函数。

Global Client and Buffer Database

ION contains a device driver associated with /dev/ion. The device structure contains a database that tracks the allocated ION buffers, handles and file descriptors, all grouped by user clients and kernel clients. ION validates all client calls according to the rules of the database. For example, there is a rule that a client cannot have two handles to the same buffer.

ION包含与/dev/ion相关联的设备驱动程序。设备结构包含一个数据库,跟踪分配的ION缓冲区、句柄和文件描述符,所有这些都按用户客户端和内核客户端分组。ION根据数据库规则验证所有客户端调用。例如,有一个规则,一个客户端不能有两个句柄到同一个缓冲区。

The DMA debug facility implements a global hashtable, dma_entry_hash, to track DMA buffers, but only when the kernel was built with the CONFIG_DMA_API_DEBUG option.

DMA调试工具实现了一个全局散列表dma_entry_hash来跟踪DMA缓冲区,但只有在使用CONFIG_DMA_API_DEBUG选项构建内核时才会这样做。

Cross-architecture Usage

ION usage today is limited to architectures that run the Android kernel.

目前,ION的使用仅限于运行Android内核的架构。

DMABUF usage is cross-architecture. The DMA mapping redesign preparation patchset modified the DMA mapping code in 9 architectures besides the ARM architecture.

DMABUF的使用是跨架构的。DMA映射重新设计准备补丁集修改了除ARM架构外的9个架构中的DMA映射代码

Buffer Synchronization

ION considers buffer synchronization to be an orthogonal problem.

ION认为缓冲区同步是一个正交问题。//无法解决的问题?

DMABUF provides a pair of APIs for synchronization. The buffer-user calls dma_buf_map_attachment() whenever it wants to use the buffer for DMA . Once the DMA for the current buffer-user is over, it signals 'end-of-DMA' to the exporter via a call to dma_buf_unmap_attachment() .

DMABUF提供了一对用于同步的api。缓冲区用户在需要使用DMA缓冲区时调用dma_buf_map_attachment()。一旦当前缓冲区用户的DMA结束,它会通过调用dma_buf_unmap_attachment()向导出器发出“DMA结束”的信号。

Delayed Buffer Allocation

ION allocates the physical memory before the buffer is shared.

ION在共享缓冲区之前分配物理内存

DMABUF can defer the allocation until the first call to dma_buf_map_attachment(). The exporter of DMA buffer has the opportunity to scan all client attachments, collate their buffer constraints, then choose the appropriate backing storage.

DMABUF可以将分配延迟到第一次调用dma_buf_map_attachment()时。DMA缓冲区的导出器有机会扫描所有客户机附件,整理它们的缓冲区约束,然后选择适当的后备存储。

ION和DMABUF可以单独集成到使用Video4Linux2 API编写的多媒体应用程序中。对于ION来说,这些多媒体程序现在倾向于在Android设备上使用PMEM,因此从PMEM切换到ION的影响应该相对较小。

将DMABUF集成到Video4Linux2中则是另一回事。将videobuf2机制与DMABUF集成在一起需要10个补丁;公平地说,许多这些修订都是在DMABUF接口稳定后对其进行更改的结果。从长远来看,这种努力应该会有回报,因为基于dmabuf的共享机制是用用于CMA和IOMMU的DMA映射挂钩设计的。CMA和IOMMU承诺将减少构建Android智能手机所需的内存。

尽管ION和DMABUF服务于类似的目的,但两者并不相互排斥。Linaro统一内存管理团队已经开始将CMA集成到ION中。为了达到主线内核的释放可以引导Android用户空间的状态,显然必须保留/dev/ion到用户空间的接口。但是在内核中,ION驱动程序可以使用一些DMABUF api来连接到CMA和IOMMU,从而利用这些子系统提供的功能。相反,DMABUF可能能够利用ION向用户空间(尤其是Android用户空间)提供统一的界面。DMABUF还可以通过采用某些ION-heap调试功能从而变得对开发人员更加友好。到目前为止,许多迹象表明Linaro,Google和内核社区正在共同努力,将ION和DMABUF的综合实力带入主线内核。----这也是我们最近能看到的。

 

评论


dma_buf attach/detach 函数的细微校正:它们仅用于重新配置pipeline;exporter被允许延迟分配到map的时间和需要,因为只有到那时所有的设备将被attach。类似地,map/unmap应该加强缓存的一致性和同步,而不是attach/detach。我们可能会添加一个扩展,允许使用持久的设备映射流dma



还要注意的是,map/unmap并不像gl同步对象那样同步hw访问。这是缓冲区共享和dma缓冲区分配的一个正交问题。但这也是我们需要在内核中支持的,因为某些SoC具有基于硬件的信号灯和邮箱以同步不同的块,而不会唤醒CPU。



 




发表于二月22,2012 1:42 UTC(星期三)通过zengtm(guest,#74989)[链接]



这篇文章中,它确实说了map/unmap是处理缓存一致性和缓冲区同步的地方。我是否有措辞表明attach/detach是为了同步?
我也同意,持久设备映射似乎是更常见的智能手机用例



 


发表于2012年2月11日16:24 UTC(Sat)由arnd(订阅者,#8866)[链接]



修改ion代码应该不会太难,这样它就可以成为dma_buf文件描述符的提供者,并集成到该框架中

当我们讨论dma_buf的设计时,有意让任意子系统提供将dma_buf文件描述符分发到用户空间的接口,尽管到目前为止的重点是让drm为已经管理的缓冲区提供描述符。如果我对文章的理解正确,那么ion的设计就是您总是必须事先知道如何通过ion ioctl分配缓冲区,然后才能将其传递给使用它的任何驱动程序。

我们可能应该研究统一这两个的内核内接口,因为它们已经非常相似。并使ION_IOC_SHARE返回一个dma_buf描述符,该描述符可以传递到任何启用了dma_buf的驱动程序中。然后可以将ion_import_fd函数替换为更抽象的dma_buf等效项。



 


发表于Feb 22,2012 1:44 UTC(Wed)by zengtm(guest,#74989)[链接]



“ ion的设计是您始终必须事先知道如何分配缓冲区”:答案是肯定的,基于ION实现,我有机会在当前的Android 4.0.x版本中进行研究。



 



发表于2013年5月19日6:54 UTC(Sun)通过abai(guest,#91041)[链接]



如果用户空间更改了ion存储器的内容,如何在用户空间将cache刷新为内存?
我看到ION_IOC_SYNC仅用于内核空间,它无法刷新用户缓存,对吗?



 




发表于二月29,2012 20:43 UTC(星期三)由cliveb(guest,#83236)[链接]



如何从用户空间获取分配的内存的物理地址?



 




发表于Mar 14,2012 17:01 UTC(Wed)by zengtm(guest,#74989)[链接]



您无法从用户空间获取物理地址:如果考虑的话,这是不安全的。



 



vkkashyap发表于2013年1月4日13:29 UTC(Fri)(Guest,#88623)[链接]



感谢您的精彩文章。

-您预见到哪种类型的安全风险?
-您看到将物理地址api限制为内核空间的其他原因吗?

 

simonwan(客人,#109625)[链接]


感谢您的文章,这对我理解ION真的很有帮助。

现在,我正在编写一个简单的测试程序,以更好地了解ION设备,但是在尝试分配内存时总是出现错误-19。你以前遇到这个错误吗?

我正在考虑这是由于缺少许可引起的,但我不确定。我注意到该文章提到在分配程序之前应先授予该程序许可权,但我不知道如何执行此操作,您能给我一些建议吗?

谢谢。



 


excors(订阅者,#95769)[链接]



唯一必要的权限应该是对/ dev / ion的读取访问权限,如果您没有该权限,您甚至将无法打开设备。

错误-19是-ENODEV,并且我认为ion_alloc仅在分配请求中没有与heap_id_mask相匹配的堆时才返回该值,因此应检查是否正确设置了该值。/ sys / kernel / debug / ion / heaps /应该列出设备上可用的堆(尽管您可能需要阅读内核头文件才能找到它们的枚举定义)。

还要检查您是否在调用正确版本的内核API-自从撰写本文以来,许多细节已更改(例如,堆掩码现在是ion_allocation_data中的一个单独字段,而不是标志的一部分),因此您应该使用libion或从您的特定设备读取内核源代码。

 




Android ION内存分配器



simonwan(访客,#109625)[链接]



嗨,exors,

谢谢您的答复。我在Android上测试了该程序,并检查了/ ion / heaps,同时获得了“ adsp,audio,kmalloc,mm,qsecom,system”的结果,但我不知道在哪里可以找到枚举定义,请问给我一些建议?

 




Android ION内存分配器



 excors(subscriber,#95769)[链接]

看起来像是高通设备,所以我认为您需要msm_ion.h中的ion_heap_ids

(不同版本和不同设备上的定义可能会有所不同-理想情况下,您应该找到特定设备的内核源。不过,大多数类似世代的Qualcomm设备可能都是兼容的。)

如果您使用的是libion,请在将heap_mask设置为例如(1 << ION_SYSTEM_HEAP_ID)的情况下调用ion_alloc以使用系统堆。(如果您不使用libion,请查看其实现,以了解如何直接调用ioctl。)

如果要与非CPU硬件(例如GPU或摄像头)共享离子缓冲区,则可能需要使用其他堆中的一个,但是在任何地方都没有记录限制,因此您必须猜测。

在非Qualcomm设备上,您可能需要将heap_mask设置为例如(1 << ION_HEAP_TYPE_SYSTEM),因为其他一些供应商使用这些HEAP_TYPE枚举作为堆ID,而不是发明一套全新的ID-这里没有通用标准。堆配置要么硬编码到内核源中,要么从设备树中加载,因此,如果要查找其他设备的详细信息,则必须到那里。



 




Android ION内存分配器



(访客,#112868)[链接]



从内存统计方面,我希望知道为ion内存分配了多少页。
在structure(ion_buffer)中,有一个成员变量'pages',

它是否保存分配给离子存储器的所有页面; 在迭代列表之后,我们将获得系统中用于离子存储的详尽页面列表?
请指导是否有人尝试过; 或者理解是否正确。
==========================================

struct page **pages;
63 * @pages: flat array of pages in the buffer -- used by fault
 64 * handler and only valid for buffers that are faulted in
 71*/72struct ion_buffer {
 73 struct kref ref;
 74 union {
 75 struct rb_node node;
 76 struct list_head list;
 77 };
 78 struct ion_device *dev;
 79 struct ion_heap *heap;
 80 unsigned long flags;
 81 unsigned long private_flags;
 82 size_t size;
 83 union {
 84 void *priv_virt;
 85 ion_phys_addr_t priv_phys;
 86 };
 87 struct mutex lock;
 88 int kmap_cnt;
 89 void *vaddr;
 90 struct sg_table *sg_table;
 91 struct page **pages;
 92 struct list_head vmas;
 93 /* used to track orphaned buffers */
 94 int handle_count;
 95 char task_comm[TASK_COMM_LEN];
 96 pid_t pid;
 97};
=========================================

 

CMA简介

::http://www.wowotech.net/memory_management/cma.html

CMA,Contiguous Memory Allocator,是内存管理子系统中的一个模块,负责物理地址连续的内存分配。一般系统会在启动过程中,从整个memory中配置一段连续内存用于CMA,然后内核其他的模块可以通过CMA的接口API进行连续内存的分配。CMA的核心并不是设计精巧的算法来管理地址连续的内存块,实际上它的底层还是依赖内核伙伴系统这样的内存管理机制,或者说CMA是处于需要连续内存块的其他内核模块(例如DMA mapping framework)和内存管理模块之间的一个中间层模块,主要功能包括:

1、解析DTS或者命令行中的参数,确定CMA内存的区域,这样的区域我们定义为CMA area。

2、提供cma_alloc和cma_release两个接口函数用于分配和释放CMA pages

3、记录和跟踪CMA area中各个pages的状态

4、调用伙伴系统接口,进行真正的内存分配::CMA并不进行内存管理,它只是”内存管理机制“的搬运工。CMA area的内存最终还是要并入伙伴系统进行管理。