android之ION內(nèi)存管理器(1)-- 簡介

為什么需要ION

回顧2011年末[2],LWN審查了android kernel patch[3],以期望將這些patch合并到kernel主線中。但是PMEM(android實現(xiàn)的 一個內(nèi)存分配器)使這個愿望破滅了。為什么PMEM不被linux 社區(qū)接受的原因在[3]中有講到。從那開始,PMEM很明確會被完全拋棄,取而代之的是ION內(nèi)存管理器。ION是google在Android4.0 ICS為了解決內(nèi)存碎片管理而引入的通用內(nèi)存管理器,它會更加融合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,實現(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: 由客戶自己定義


    ION框架圖

下圖是兩個client共享內(nèi)存的示意圖。圖中有2個heap(每種heap都有自己的內(nèi)存分配策略),每個heap中分配了若干個buffer。client的handle管理到對應(yīng)的buffer。兩個client是通過文件描述符fd來實現(xiàn)內(nèi)存共享的。


ION共享內(nèi)存的示意圖

ION APIs

用戶空間 API

定義了6種 ioctl 接口,可以與用戶應(yīng)用程序交互。

  • ION_IOC_ALLOC: 分配內(nèi)存
  • ION_IOC_FREE: 釋放內(nèi)存
  • ION_IOC_MAP: 獲取文件描述符進行mmap (? 在code中未使用這個定義)
  • ION_IOC_SHARE: 創(chuàng)建文件描述符來實現(xiàn)共享內(nèi)存
  • ION_IOC_IMPORT: 獲取文件描述符
  • ION_IOC_CUSTOM: 調(diào)用用戶自定義的ioctl
  • ION_IOC_SHARE 及ION_IOC_IMPORT是基于DMABUF實現(xiàn)的,所以當(dāng)共享進程獲取文件描述符后,可以直接調(diào)用mmap來操作共享內(nèi)存。mmap實現(xiàn)由DMABUF子系統(tǒng)調(diào)用ION子系統(tǒng)中mmap回調(diào)函數(shù)完成。

內(nèi)核空間 API

內(nèi)核驅(qū)動也可以注冊為一個ION的客戶端(client),可以選擇使用哪種類型的heap來申請內(nèi)存。

  • ion_client_create: 分配一個客戶端。
  • ion_client_destroy: 釋放一個客戶端及綁定在它上面的所有ion handle.
  • ion handle: 這里每個ion handle映射到一個buffer中,每個buffer關(guān)聯(lián)一個heap。也就是說一個客戶端可以操作多塊buffer。

Buffer 申請及釋放函數(shù):

  • ion_alloc: 申請ion內(nèi)存,返回ion handle

  • ion_free: 釋放ion handle
    ION 通過handle來管理buffer,驅(qū)動需要可以訪問到buffer的地址。ION通過下面的函數(shù)來達到這個目的

  • 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地址來實現(xiàn)驅(qū)動間共享內(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

Heap API

Heap 接口定義 [drivers/gpu/ion/ion_priv.h]

這些接口不是暴露給驅(qū)動或者用戶應(yīng)用程序的。

/**
 * struct ion_heap_ops - ops to operate on a given heap
 * @allocate:           allocate memory
 * @free:               free memory
 * @phys                get physical address of a buffer (only define on physically contiguous heaps)
 * @map_dma             map the memory for dma to a scatterlist
 * @unmap_dma           unmap the memory for dma
 * @map_kernel          map memory to the kernel
 * @unmap_kernel        unmap memory to the kernel
 * @map_user            map memory to userspace
 */
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 *mapper, struct ion_buffer *buffer, struct vm_area_struct *vma);
};

ION debug

ION 在/sys/kernel/debug/ion/ 提供一個debugfs 接口。

每個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

每個由pid標(biāo)識的client也有一個debugfs目錄/sys/kernel/debug/ion/<<pid>>

$cat /sys/kernel/debug/ion/2890 
       heap_name:    size_in_bytes
      ion-heap-1:    40960 11

參考文獻

  1. https://wiki.linaro.org/BenjaminGaignard/ion

  2. http://lwn.net/Articles/480055/

  3. http://lwn.net/Articles/472984/

原文鏈接:https://blog.csdn.net/crazyjiang/article/details/7927260

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容