Android的pmem分析

        pmem是android为DSP vpu gpu等设备提供的一种内存分配机制,我们都知道vpu gpu这一类设备需要大块的连续物理内存以便进行硬件解码,硬件显示加速。PMEM就像一个小型的buddy内存管理系统,独立于linux kernel内存管理模块管理,不会受到内存管理中的外碎片的影响,同时还可以灵活的提供额外功能。

当然在系统运行一段时间后,PMEM也同样面临着外碎片问题,因此PMEM内存区的使用者尽量分配大块的内存,而不是零星的小内存。

应用层使用方法

1. 分配的内存只在一个进程中使用

pmem_fd = open("/dev/pmem_gpu", O_RDWR, 0);

pmem_base = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, pmem_fd, 0);


2. 不同进程间共享。这利用了PMEM 驱动的Connect功能

进程1:

pmem_fd0 = open("/dev/pmem_gpu", O_RDWR, 0);

pmem_base  = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, pmem_fd0, 0);

进程2:

pmem_fd1 = open("/dev/pmem_gpu", O_RDWR, 0);

ret = ioctl(pmem_fd1, PMEM_CONNECT, pmem_fd0);

ret = ioctl(pmem_fd1, PMEM_MAP, &region1);

一个进程打开PMEM设备,通过mmap操作映射内存到进程空间,该进程称为PMEM的master进程。其他进程可以再次打开该设备,然后通过PMEM_CONNECT操作,pmem_fd1就和pmem_fd0获得了相同的Pmem空间,这样该进程就称为PMEM的client进程。


PMEM设备接口

内核为每一个PMEM创建一个misc 设备节点,应用层通过这个设备节点的file_operations操作PMEM设备。


内存分配:

PMEM内存是供应用空间程序使用的,kernel和驱动并不会使用PMEM。应用程序首先打开相应PMEM设备节点,使用mmap系统调用或者PMEM_MAP PMEM_ALLOCATE ioctl申请pmem内存


内存释放:

应用程序可以显示的调用PMEM_UNMAP来释放分配的pmem内存,文件release操作会释放这个PMEM设备所有分配的内存。因此只要close了文件,那么就保证所有分配的内存都被回收,防止由于用户疏忽或者程序异常造成的内存泄漏。


获取物理内存地址

sometimes,应用空间需要获取物理地址

ioctl PMEM_GET_PHYS 获取pmem内存物理地址,我们知道pmem驱动维护着多个pmem设备,并且每个pmem设备还可能进行多次分配。那么这里是如何确定请求哪个pmem设备,哪一次分配的物理地址呢?

通过设备节点的从设备号,就可以确定这次请求的pmem设备;此外在file结构的private_data是一个pmem_data结构,pmem_data->index指向了最后一次分配的索引位置。因此PMEM_GET_PHYS获取的是这个pmem设备最后一次分配内存的起始物理地址。


PMEM_GET_SIZE, PMEM_GET_TOTAL_SIZE

PMEM_GET_SIZE用来获取给定PMEM设备最后一次分配的size;而PMEM_GET_TOTAL_SIZE则获取给定PMEM的整个空间size


PMEM_CACHE_FLUSH

刷新给定内存区的cache,dmac_flush_range包括writeback和invalidate操作,使得写cache写回,读cache无效



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章