ION debug
ION 在/sys/kernel/debug/ion/ 提供一個(gè)debugfs 接口。
每個(gè)heap都有自己的debugfs目錄,client內(nèi)存使用狀況顯示在/sys/kernel/debug/ion/<<heap name>>
$cat /sys/kernel/debug/ion/ion-heap-1
client pid size
test_ion 2890 16384
每個(gè)由pid標(biāo)識(shí)的client也有一個(gè)debugfs目錄/sys/kernel/debug/ion/<<pid>>
$cat /sys/kernel/debug/ion/2890
heap_name: size_in_bytes
ion-heap-1: 40960 11
為什么需要ION
回顧2011年末[2],LWN審查了android kernel patch[3],以期望將這些patch合并到kernel主線中。但是PMEM(android實(shí)現(xiàn)的 一個(gè)內(nèi)存分配器)使這個(gè)愿望破滅了。為什么PMEM不被linux 社區(qū)接受的原因在[3]中有講到。從那開始,PMEM很明確會(huì)被完全拋棄,取而代之的是ION內(nèi)存管理器。ION是google在Android4.0 ICS為了解決內(nèi)存碎片管理而引入的通用內(nèi)存管理器,它會(huì)更加融合kernel。目前QCOM MSM, NVDIA Tegra, TI OMAP, MRVL PXA都用ION替換PMEM。
如何獲取source code
http://android.googlesource.com/kernel/common.git
ION codes reside in drivers/gpu/ion
Specific usage examples on omap4:
http://android.googlesource.com/kernel/omap.git
ION 框架[1]
ION 定義了四種不同的heap,實(shí)現(xiàn)不同的內(nèi)存分配策略。
- ION_HEAP_TYPE_SYSTEM : 通過vmalloc分配內(nèi)存
- ION_HEAP_TYPE_SYSTEM_CONTIG: 通過kmalloc分配內(nèi)存
- ION_HEAP_TYPE_CARVEOUT: 在保留內(nèi)存塊中(reserve memory)分配內(nèi)存
- ION_HEAP_TYPE_CUSTOM: 由客戶自己定義
下圖是兩個(gè)client共享內(nèi)存的示意圖。圖中有2個(gè)heap(每種heap都有自己的內(nèi)存分配策略),每個(gè)heap中分配了若干個(gè)buffer。client的handle管理到對(duì)應(yīng)的buffer。兩個(gè)client是通過文件描述符fd來實(shí)現(xiàn)內(nèi)存共享的。
ION APIs
用戶空間 API
定義了6種 ioctl 接口,可以與用戶應(yīng)用程序交互。
- ION_IOC_ALLOC: 分配內(nèi)存
- ION_IOC_FREE: 釋放內(nèi)存
- ION_IOC_MAP: 獲取文件描述符進(jìn)行mmap (? 在code中未使用這個(gè)定義)
- ION_IOC_SHARE: 創(chuàng)建文件描述符來實(shí)現(xiàn)共享內(nèi)存
- ION_IOC_IMPORT: 獲取文件描述符
- ION_IOC_CUSTOM: 調(diào)用用戶自定義的ioctl
ION_IOC_SHARE 及ION_IOC_IMPORT是基于DMABUF實(shí)現(xiàn)的,所以當(dāng)共享進(jìn)程獲取文件描述符后,可以直接調(diào)用mmap來操作共享內(nèi)存。mmap實(shí)現(xiàn)由DMABUF子系統(tǒng)調(diào)用ION子系統(tǒng)中mmap回調(diào)函數(shù)完成。
內(nèi)核空間 API
內(nèi)核驅(qū)動(dòng)也可以注冊(cè)為一個(gè)ION的客戶端(client),可以選擇使用哪種類型的heap來申請(qǐng)內(nèi)存。
- ion_client_create: 分配一個(gè)客戶端。
- ion_client_destroy: 釋放一個(gè)客戶端及綁定在它上面的所有ion handle.
ion handle: 這里每個(gè)ion handle映射到一個(gè)buffer中,每個(gè)buffer關(guān)聯(lián)一個(gè)heap。也就是說一個(gè)客戶端可以操作多塊buffer。
Buffer 申請(qǐng)及釋放函數(shù):
- ion_alloc: 申請(qǐng)ion內(nèi)存,返回ion handle
- ion_free: 釋放ion handle
ION 通過handle來管理buffer,驅(qū)動(dòng)需要可以訪問到buffer的地址。ION通過下面的函數(shù)來達(dá)到這個(gè)目的
- ion_phys: 返回buffer的物理地址(address)及大小(size)
- ion_map_kernel: 給指定的buffer創(chuàng)建內(nèi)核內(nèi)存映射
- ion_unmap_kernel: 銷毀指定buffer的內(nèi)核內(nèi)存映射
- ion_map_dma: 為指定buffer創(chuàng)建dma 映射,返回sglist(scatter/gather list)
- ion_unmap_dma: 銷毀指定buffer的dma映射
ION是通過handle而非buffer地址來實(shí)現(xiàn)驅(qū)動(dòng)間共享內(nèi)存,用戶空間共享內(nèi)存也是利用同樣原理。
- ion_share: given a handle, obtain a buffer to pass to other clients
- ion_import: given an buffer in another client, import it
- ion_import_fd: given an fd obtained via ION_IOC_SHARE ioctl, import it