Android pmem分析

來源:互聯網
上載者:User

最近在最佳化mx51項目中記憶體的使用,512MB RAM的劃分為:

64MB pmem_adsp

64MB pmem gpu

96MB DMA zone

96MB GPU memory

這樣只剩下192M給kernel 的Normal zone,由於普通的alloc_pages無法使用DMA zone的空間,記憶體相當緊張,想從pmem中釋放一些記憶體出來,因此花了點時間瞭解pmem.

pmem是android為DSP vpu gpu等裝置提供的一種記憶體配置機制,我們都知道vpu gpu這一類裝置需要大塊的連續實體記憶體以便進行硬體解碼,硬體顯示加速。PMEM就像一個小型的buddy記憶體管理系統,獨立於linux kernel記憶體管理模組管理,不會受到記憶體管理中的外片段的影響,同時還可以靈活的提供額外功能。

當然在系統運行一段時間後,PMEM也同樣面臨著外片段問題,因此PMEM記憶體區的使用者盡量分配大塊的記憶體,而不是零星的小記憶體。

pmem記憶體區使用方式:

PMEM_DEBUG控制pmem驅動是否提供debugfs介面

進入開發板後,可以通過如下命令安裝debugfs檔案系統

# mount -t debugfs none /sys/kernel/debug

# ls /sys/kernel/debug/
asoc
binder
hid
pmem_gpu
pmem_adsp
bluetooth
mmc3
mmc2
mmc1
mmc0
usb
gpio
bdi

其中pmem_gpu是為GPU顯示加速提供的記憶體配置區,pmem_adsp是為vpu解碼提供的記憶體非配區

可以使用cat命令查看pmem的使用方式:

# cat /sys/kernel/debug/pmem_gpu

# cat /sys/kernel/debug/pmem_adsp

應用程式層使用方法

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進程。

Kernel空間PMEM driver分析

資料結構

圖是網上偷來的

pmem[0]和pmem[1]

是pmem_info結構,每一個PMEM裝置都有一個pmem_info結構

struct pmem_info {
    struct miscdevice dev;
    unsigned long base;
    unsigned char __iomem *vbase;
    unsigned long size;
    unsigned long num_entries;
    unsigned long garbage_pfn;
    int garbage_index;
    struct pmem_bits *bitmap;
    unsigned no_allocator;
    unsigned cached;
    unsigned buffered;
    unsigned allocated;
    struct semaphore data_list_sem;
    struct list_head data_list;
    struct rw_semaphore bitmap_sem;

    long (*ioctl)(struct file *, unsigned int, unsigned long);
    int (*release)(struct inode *, struct file *);
};

@dev: PMEM裝置被註冊在misc裝置下

@base: 是這個PMEM裝置對應的實體記憶體地址

@vbase: 是實體記憶體remap後得到的核心虛擬位址

@size: pmem裝置的總容量,從驅動本身來說並不要求2次冪大小,但是imx51強製為2次冪,否則android無法啟動

@num_entries: pmem最小分配單位元目,最小分配單位大小至少要為page的2次冪倍

@bitmap: 每個pmem裝置把該裝置的mem空間劃分為PMEM_MIN_ALLOC大小的配置單位,每個配置單位都對應著一個pmem_bits結構,這個pmem_bits用來描述配置單位的大小和使用方式。

@no_allocator: 這個pmem裝置,是否有記憶體 Clerk,有的pmem裝置只被一個進程使用一次,這種情況下,是不需要分配器的,整個pmem裝置的記憶體一次性的全部分配給第一個進行映射的進程。

@cached:所謂cached,就是pmem記憶體是否使能cpu 緩衝。如果需要混合使用cached和uncached記憶體,那麼可以設定這個標誌,並且使用O_SYNC標誌開啟裝置檔案來擷取uncached地區。

@allocaed:僅當no_allocator設定時有效,用來表示整個pmem空間是否被分配。

@data_list:系統的所有pmem  裝置都通過data_list串連到一起。

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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.