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無效



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