在嵌入式Linux與Android設備中,DMA-BUF作為跨進程、跨設備的內(nèi)存共享核心機制,直接決定了圖形渲染、視頻編解碼、相機采集等關(guān)鍵場景的性能表現(xiàn)。一款針對dma-buf的核心補丁add support ANDROID and RK feature,通過12個文件的深度改造與重構(gòu),為DMA-BUF機制注入了Android生態(tài)適配與RK平臺專屬優(yōu)化的雙重能力,同時完善了其底層內(nèi)存管理邏輯,是嵌入式設備內(nèi)存管理模塊的一次重要升級。
本次補丁涉及947行代碼新增、102行代碼刪除,新增3個核心組件文件,重構(gòu)DMA-Heap核心架構(gòu),從基礎組件、核心接口、平臺適配等多維度完成升級,形成了一套適配Android生態(tài)與RK平臺特性的高性能DMA-BUF內(nèi)存管理方案。
一、補丁核心目標:生態(tài)適配+性能優(yōu)化+能力完善
該補丁的開發(fā)圍繞三大核心目標展開,既解決生態(tài)兼容問題,又實現(xiàn)平臺性能調(diào)優(yōu),同時補全DMA-BUF的功能短板:
1.補全Android系統(tǒng)對DMA-BUF的功能依賴,解決跨進程內(nèi)存共享在Android生態(tài)下的兼容性問題,適配Android系統(tǒng)的內(nèi)存操作需求;
2.針對RK平臺硬件架構(gòu)特性做專屬內(nèi)存管理優(yōu)化,提升RK嵌入式設備在高頻內(nèi)存操作場景下的流暢度與穩(wěn)定性;
3.新增頁池管理、延遲釋放等底層機制,擴展DMA-BUF核心接口,強化模塊可調(diào)試性與擴展性,完善內(nèi)存管理全鏈路能力。
二、核心改動深度解析
本次補丁的改動覆蓋DMA-BUF的底層基礎組件、核心對外接口、DMA-Heap架構(gòu)、RK平臺專屬適配等多個維度,每一處調(diào)整均圍繞“適配性”與“高性能”兩大核心展開,以下為關(guān)鍵改動細節(jié),搭配具體代碼片段及解析:
(一)新增兩大基礎組件,重構(gòu)內(nèi)存管理底層邏輯
補丁新增延遲釋放助手與頁池管理兩大核心基礎組件,從根源上解決嵌入式設備高頻內(nèi)存操作中易出現(xiàn)的碎片化、分配延遲高等問題,為高性能內(nèi)存管理奠定基礎:
1.延遲釋放助手(deferred-free-helper.c)
?核心功能:通過內(nèi)核工作隊列實現(xiàn)內(nèi)存的異步釋放,避免同步釋放帶來的主線程阻塞,同時減少高頻內(nèi)存申請與釋放導致的內(nèi)存碎片積累;
// 延遲釋放工作隊列定義(核心代碼片段)staticstructworkqueue_struct *deferred_free_wq;staticstructwork_struct deferred_free_work;// 初始化延遲釋放助手intdeferred_free_helper_init(void){ deferred_free_wq = create_singlethread_workqueue("dmabuf-deferred-free-worker"); if(!deferred_free_wq) return-ENOMEM; INIT_WORK(&deferred_free_work, deferred_free_worker); return0;}EXPORT_SYMBOL_GPL(deferred_free_helper_init);
// 異步釋放核心邏輯staticvoiddeferred_free_worker(struct work_struct *work) { struct deferred_free_node *node, *tmp; spin_lock(&deferred_free_lock); list_for_each_entry_safe(node, tmp, &deferred_free_list, list) { list_del(&node->list); __free_pages(node->page, node->order);// 批量釋放內(nèi)存頁 kfree(node); } spin_unlock(&deferred_free_lock);}
代碼解析:①定義專屬工作隊列deferred_free_wq和工作線程dmabuf-deferred-free-worker,專門處理內(nèi)存異步釋放;②deferred_free_helper_init完成初始化,創(chuàng)建單線程工作隊列并綁定工作函數(shù);③工作函數(shù)deferred_free_worker通過自旋鎖保護全局鏈表,批量遍歷并釋放待釋放內(nèi)存頁,避免高頻單次釋放導致的碎片。
?智能釋放策略:維護全局空閑鏈表與等待隊列,通過專屬內(nèi)核工作線程處理內(nèi)存釋放邏輯;內(nèi)存壓力較小時異步批量釋放,內(nèi)存緊張時通過shrinker機制觸發(fā)同步優(yōu)先釋放,平衡性能與系統(tǒng)資源利用率;
// shrinker機制適配(核心代碼片段)staticunsignedlongdeferred_free_shrinker_count(structshrinker *shrink, structshrink_control *sc) { returndeferred_free_count;// 返回待釋放內(nèi)存頁數(shù)量}staticunsignedlongdeferred_free_shrinker_scan(structshrinker *shrink, structshrink_control *sc) { unsignedlongfreed =0; // 內(nèi)存緊張時,同步釋放部分內(nèi)存頁 freed =deferred_free_sync_release(sc->nr_to_scan); returnfreed;}staticstructshrinkerdeferred_free_shrinker = { .count_objects = deferred_free_shrinker_count, .scan_objects = deferred_free_shrinker_scan, .seeks = DEFAULT_SEEKS,};
代碼解析:注冊shrinker回調(diào)函數(shù),當系統(tǒng)內(nèi)存緊張時,內(nèi)核會調(diào)用deferred_free_shrinker_scan同步釋放指定數(shù)量的內(nèi)存頁,優(yōu)先保障系統(tǒng)內(nèi)存可用;內(nèi)存壓力小時,仍通過工作隊列異步批量釋放,實現(xiàn)“性能優(yōu)先+應急保障”的雙重策略。
?精細化管理:支持按頁計數(shù)的內(nèi)存管理,精準統(tǒng)計與控制待釋放內(nèi)存量,適配嵌入式設備有限的內(nèi)存資源場景。
2.頁池管理(page_pool.c/h)
?核心功能:實現(xiàn)內(nèi)存頁的預分配與復用,在系統(tǒng)啟動或空閑時預分配低內(nèi)存(POOL_LOWPAGE)與高內(nèi)存(POOL_HIGHPAGE)頁塊,形成可直接復用的內(nèi)存池,大幅減少動態(tài)內(nèi)存分配的開銷;
// 頁池初始化(核心代碼片段)structdmabuf_page_pool *dmabuf_page_pool_create(enumpool_type type,unsignedintorder) { structdmabuf_page_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL); if(!pool) returnNULL; pool->type = type; pool->order = order; spin_lock_init(&pool->lock); INIT_LIST_HEAD(&pool->free_list); pool->size =0; // 預分配內(nèi)存頁(根據(jù)池類型分配低/高內(nèi)存) if(type == POOL_LOWPAGE) pool->pages = alloc_pages(GFP_KERNEL | __GFP_LOWMEM, order); else pool->pages = alloc_pages(GFP_KERNEL, order); if(!pool->pages) { kfree(pool); returnNULL; } list_add(&pool->pages->lru, &pool->free_list); pool->size++; returnpool;}EXPORT_SYMBOL_GPL(dmabuf_page_pool_create);
代碼解析:①頁池創(chuàng)建時,根據(jù)類型(低內(nèi)存/高內(nèi)存)預分配指定“階”(order)的內(nèi)存頁,階數(shù)決定內(nèi)存塊大?。╫rder=0對應1頁,order=1對應2頁,以此類推);②用鏈表管理空閑內(nèi)存頁,通過自旋鎖保證多線程安全,后續(xù)內(nèi)存申請時可直接從空閑鏈表取頁,無需重新動態(tài)分配。
?關(guān)鍵特性:支持按內(nèi)存“階”(order)分配,適配不同大小的內(nèi)存申請需求;提供池的創(chuàng)建、銷毀、內(nèi)存分配、釋放、大小查詢的完整接口;集成shrinker機制,系統(tǒng)內(nèi)存緊張時自動回收池內(nèi)空閑頁塊,保證系統(tǒng)內(nèi)存可用;
// 頁池內(nèi)存分配接口(核心代碼片段)structpage *dmabuf_page_pool_alloc(structdmabuf_page_pool *pool) { structpage *page = NULL; spin_lock(&pool->lock); if(!list_empty(&pool->free_list)) { page = list_first_entry(&pool->free_list,structpage, lru); list_del(&page->lru); pool->size--; } spin_unlock(&pool->lock); // 若池內(nèi)無空閑頁,動態(tài)分配補充(兜底邏輯) if(!page) { page = alloc_pages(GFP_KERNEL | (pool->type == POOL_LOWPAGE ? __GFP_LOWMEM :0), pool->order); } returnpage;}
代碼解析:分配內(nèi)存時優(yōu)先從頁池空閑鏈表取頁,無空閑頁時再動態(tài)分配,既減少分配開銷,又通過兜底邏輯保證內(nèi)存可用性;分配過程用自旋鎖保護,避免多線程競爭導致的異常。
?生態(tài)適配價值:完美匹配Android系統(tǒng)中圖形緩沖區(qū)、視頻幀、相機采集數(shù)據(jù)等高頻復用的內(nèi)存場景,將內(nèi)存分配延遲大幅降低,提升實時性。
(二)擴展核心接口家族,適配Android精細化操作需求
為滿足Android系統(tǒng)對內(nèi)存操作的精細化、高實時性要求,補丁對DMA-BUF的核心對外接口進行了擴展與公開,同時保證對原有接口的兼容:
1.新增局部CPU訪問接口
新增dma_buf_begin_cpu_access_partial與dma_buf_end_cpu_access_partial接口,支持指定偏移量與長度的局部內(nèi)存同步,替代原有僅支持全量內(nèi)存同步的邏輯;
+int dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf,+ enum dma_data_direction direction,+ unsigned int offset, unsigned int len)+{+ int ret = 0;++ if (WARN_ON(!dmabuf))+ return -EINVAL;++ if (dmabuf->ops->begin_cpu_access_partial)+ ret = dmabuf->ops->begin_cpu_access_partial(dmabuf, direction,+ offset, len);++ /* Ensure that all fences are waited upon - but we first allow+ * the native handler the chance to do so more efficiently if it+ * chooses. A double invocation here will be reasonably cheap no-op.+ */+ if (ret == 0)+ ret = __dma_buf_begin_cpu_access(dmabuf, direction);++ return ret;+}+EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access_partial);
代碼解析:①接口接收偏移量(offset)和長度(length)參數(shù),先校驗參數(shù)合法性(避免內(nèi)存越界);②遍歷所有附件(attachment),調(diào)用exporter自定義的局部同步邏輯,保證接口兼容性;③新增柵欄等待邏輯,確保CPU與DMA設備的內(nèi)存數(shù)據(jù)一致,避免數(shù)據(jù)錯亂;④僅同步指定范圍的內(nèi)存,大幅減少緩存刷新開銷。
?核心優(yōu)勢:避免整段內(nèi)存的無意義緩存刷新,在視頻幀局部更新、圖形紋理部分修改等場景下,可大幅減少同步耗時,提升內(nèi)存操作效率;
?兼容設計:保留原有全量同步接口,通過回調(diào)機制支持exporter自定義局部同步邏輯,實現(xiàn)新舊接口平滑過渡。
2.新增緩沖區(qū)屬性查詢接口
新增dma_buf_get_flags接口,支持獲取DMA-BUF緩沖區(qū)的關(guān)鍵屬性(如緩存類型、設備訪問權(quán)限等),解決Android系統(tǒng)對內(nèi)存屬性的精準判斷需求,避免因?qū)傩圆黄ヅ鋵е碌目缒K協(xié)作兼容性問題。
+int dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags)+{+ int ret = 0;++ if (WARN_ON(!dmabuf) || !flags)+ return -EINVAL;++ if (dmabuf->ops->get_flags)+ ret = dmabuf->ops->get_flags(dmabuf, flags);++ return ret;+}+EXPORT_SYMBOL_GPL(dma_buf_get_flags);
代碼解析:①接口簡潔高效,直接返回DMA-BUF結(jié)構(gòu)體中的flags字段;② flags字段通過位運算存儲多種屬性(緩存類型、訪問權(quán)限等),Android內(nèi)核模塊(如SurfaceFlinger)可通過該接口快速判斷內(nèi)存屬性,避免因?qū)傩圆黄ヅ鋵е碌匿秩井惓!?shù)據(jù)讀寫失敗等問題。
3.公開文件類型判斷接口
將原靜態(tài)內(nèi)部接口is_dma_buf_file修改為公開導出接口(EXPORT_SYMBOL_NS_GPL),方便Android內(nèi)核核心模塊(如SurfaceFlinger、MediaServer)快速判斷文件是否關(guān)聯(lián)DMA-BUF,提升跨模塊內(nèi)存協(xié)作的效率。
-staticinlineintis_dma_buf_file(structfile*file)+intis_dma_buf_file(structfile*file){ returnfile->f_op == &dma_buf_fops;}+EXPORT_SYMBOL_NS_GPL(is_dma_buf_file, DMA_BUF);
代碼解析:通過判斷文件的操作符(f_op)是否為DMA-BUF專屬操作符(dma_buf_fops),快速識別文件類型;接口從靜態(tài)改為公開導出后,Android內(nèi)核核心模塊可直接調(diào)用,無需重復實現(xiàn)判斷邏輯,提升跨模塊協(xié)作效率。
(三)重構(gòu)DMA-Heap架構(gòu),強化內(nèi)存分配源頭管理
DMA-Heap作為DMA-BUF的內(nèi)存分配源頭,其架構(gòu)設計直接影響內(nèi)存分配效率,本次補丁對DMA-Heap進行了架構(gòu)級重構(gòu),從數(shù)據(jù)結(jié)構(gòu)、接口設計、可調(diào)試性等方面完成全面升級:
1.增強核心數(shù)據(jù)結(jié)構(gòu)
在struct dma_heap中新增引用計數(shù)(kref)與設備結(jié)構(gòu)體(heap_dev),解決多進程、多模塊訪問時的資源泄漏問題,同時強化DMA-Heap與硬件設備驅(qū)動的綁定能力,適配RK平臺硬件架構(gòu)特性。
// DMA-Heap數(shù)據(jù)結(jié)構(gòu)增強(核心代碼片段)structdma_heap{ constchar*name; conststructdma_heap_ops*ops; structlist_headlist; structkrefrefcount;// 新增:引用計數(shù),用于生命周期管理 structdevice*heap_dev;// 新增:關(guān)聯(lián)設備結(jié)構(gòu)體,綁定硬件驅(qū)動 structdentry*sysfs_entry;// 新增:sysfs節(jié)點,用于調(diào)試監(jiān)控};// 引用計數(shù)釋放函數(shù)(配套實現(xiàn))staticvoiddma_heap_release(structkref *kref){ structdma_heap*heap =container_of(kref,structdma_heap, refcount); kfree(heap);}// 引用計數(shù)獲取與釋放接口voiddma_heap_get(structdma_heap *heap){ kref_get(&heap->refcount);}voiddma_heap_put(structdma_heap *heap){ kref_put(&heap->refcount, dma_heap_release);}EXPORT_SYMBOL_NS_GPL(dma_heap_put, DMA_BUF);
代碼解析:①新增引用計數(shù)(refcount),通過dma_heap_get(獲取引用)和dma_heap_put(釋放引用)接口,實現(xiàn)DMA-Heap的生命周期精細化管理,避免多進程訪問時的資源泄漏;②新增設備結(jié)構(gòu)體(heap_dev),將DMA-Heap與具體硬件設備綁定,適配RK平臺不同設備的內(nèi)存布局差異;③新增sysfs節(jié)點(sysfs_entry),為后續(xù)調(diào)試監(jiān)控提供支撐。
2.拆分與擴展核心接口
?拆分內(nèi)存分配接口:新增dma_heap_buffer_alloc(返回dma_buf結(jié)構(gòu)體)與dma_heap_bufferfd_alloc(返回文件描述符),分別適配內(nèi)核態(tài)與用戶態(tài)的內(nèi)存申請場景,提升接口調(diào)用的靈活性;
// 內(nèi)核態(tài)內(nèi)存分配接口(新增)structdma_buf*dma_heap_buffer_alloc(structdma_heap *heap,size_tsize, unsignedintflags) { if(!heap || !heap->ops || !heap->ops->alloc) returnERR_PTR(-EINVAL); returnheap->ops->alloc(heap, size, flags);// 調(diào)用具體堆的分配邏輯}EXPORT_SYMBOL_NS_GPL(dma_heap_buffer_alloc, DMA_BUF);// 用戶態(tài)內(nèi)存分配接口(新增)intdma_heap_bufferfd_alloc(structdma_heap *heap,size_tsize, unsignedintflags,unsignedintfd_flags) { structdma_buf*dmabuf; intfd; dmabuf =dma_heap_buffer_alloc(heap, size, flags); if(IS_ERR(dmabuf)) returnPTR_ERR(dmabuf); // 生成文件描述符,供用戶態(tài)進程使用 fd =dma_buf_fd(dmabuf, fd_flags); dma_buf_put(dmabuf); returnfd;}EXPORT_SYMBOL_NS_GPL(dma_heap_bufferfd_alloc, DMA_BUF);
代碼解析:①內(nèi)核態(tài)接口返回dma_buf結(jié)構(gòu)體,供內(nèi)核模塊直接操作內(nèi)存;②用戶態(tài)接口返回文件描述符(fd),符合Android用戶態(tài)進程的內(nèi)存操作規(guī)范,用戶態(tài)進程可通過fd訪問DMA-BUF內(nèi)存;③接口拆分后,內(nèi)核態(tài)與用戶態(tài)的內(nèi)存申請邏輯分離,提升代碼可讀性與維護性。
?完善生命周期管理接口:新增dma_heap_find(按名稱查找內(nèi)存堆)、dma_heap_put(釋放內(nèi)存堆引用)、dma_heap_get_dev(獲取堆關(guān)聯(lián)設備)等接口,實現(xiàn)內(nèi)存堆從創(chuàng)建到銷毀的全生命周期精細化管理;
?公開基礎操作接口:將dma_heap_get_drvdata、dma_heap_get_name等接口公開導出,方便上層模塊與第三方驅(qū)動的調(diào)用。
3.強化可調(diào)試性與監(jiān)控能力
新增sysfs系統(tǒng)節(jié)點/sys/kernel/dma_heap/total_pools_kb,實時展示系統(tǒng)中所有DMA-Heap內(nèi)存池的總占用量,開發(fā)者可通過該節(jié)點快速定位內(nèi)存泄漏、資源浪費等問題,為Android設備與RK平臺的性能調(diào)優(yōu)提供關(guān)鍵依據(jù)。

// sysfs節(jié)點創(chuàng)建與實現(xiàn)(核心代碼片段)staticssize_ttotal_pools_kb_show(structkobject *kobj,structkobj_attribute *attr,char*buf){ unsignedlongtotal =0; structdma_heap*heap; mutex_lock(&dma_heap_lock); list_for_each_entry(heap, &dma_heaps, list) { // 累加所有內(nèi)存池的占用量(單位:KB) total +=dmabuf_page_pool_get_size(heap->pool) >>10; } mutex_unlock(&dma_heap_lock); returnsprintf(buf,"%lun", total);}// 定義sysfs屬性staticstructkobj_attributetotal_pools_kb_attr = __ATTR_RO(total_pools_kb);// 初始化sysfs節(jié)點intdma_heap_sysfs_init(void){ structkobject*dma_heap_kobj; dma_heap_kobj =kobject_create_and_add("dma_heap", kernel_kobj); if(!dma_heap_kobj) return-ENOMEM; returnsysfs_create_file(dma_heap_kobj, &total_pools_kb_attr.attr);}
代碼解析:①total_pools_kb_show函數(shù)遍歷所有DMA-Heap,通過頁池接口獲取每個堆的內(nèi)存占用量,累加后以KB為單位返回;②創(chuàng)建sysfs節(jié)點total_pools_kb,開發(fā)者可通過cat /sys/kernel/dma_heap/total_pools_kb查看實時內(nèi)存占用,快速定位內(nèi)存泄漏等問題。
4.優(yōu)化初始化與錯誤處理
重構(gòu)DMA-Heap的初始化流程,新增sysfs節(jié)點的獨立初始化與銷毀邏輯;完善資源分配失敗時的錯誤回滾機制,確保任一環(huán)節(jié)失敗后均能干凈釋放已分配資源,避免內(nèi)存泄漏。
(四)RK平臺專屬適配,精準匹配硬件架構(gòu)特性
針對RK平臺的硬件內(nèi)存布局與架構(gòu)特性,補丁對核心的CMA堆與系統(tǒng)堆進行了定制化改造,同時調(diào)整編譯配置,適配不同資源規(guī)格的RK設備:
1. RK CMA堆優(yōu)化(rk_cma_heap.c)
?vmapvunmap重構(gòu)/邏輯,全面適配iosys_map接口規(guī)范,提升虛擬內(nèi)存映射的穩(wěn)定性與兼容性;
// RK CMA堆vmap邏輯重構(gòu)(核心代碼片段)staticvoid*rk_cma_heap_vmap(structdma_buf *dmabuf,structvm_area_struct *vma){ structrk_cma_heap_buf*buf =to_rk_cma_heap_buf(dmabuf); // 適配iosys_map接口規(guī)范,替換原有vmap邏輯 returniosys_map_vmap(&buf->iosys, vma->vm_pgoff << PAGE_SHIFT,? ? ? ? ? ? ? ? ? ? ? ? ? vma->vm_end - vma->vm_start);}staticvoidrk_cma_heap_vunmap(structdma_buf *dmabuf,void*vaddr){ structrk_cma_heap_buf*buf =to_rk_cma_heap_buf(dmabuf); // 對應iosys_map的虛擬內(nèi)存釋放 iosys_map_vunmap(&buf->iosys, vaddr);}
代碼解析:將原有傳統(tǒng)vmap/vunmap邏輯,替換為iosys_map接口(嵌入式系統(tǒng)通用的內(nèi)存映射規(guī)范),適配RK平臺的硬件內(nèi)存映射機制,減少虛擬內(nèi)存映射異常,提升穩(wěn)定性。
?調(diào)整cma_alloc調(diào)用參數(shù),優(yōu)化連續(xù)內(nèi)存分配策略,精準匹配RK平臺的CMA內(nèi)存布局;
// CMA內(nèi)存分配參數(shù)優(yōu)化(核心代碼片段)staticstructdma_buf*rk_cma_heap_alloc(structdma_heap *heap,size_tsize, unsignedintflags) { structrk_cma_heap*rk_heap =to_rk_cma_heap(heap); structpage*page; // 關(guān)鍵優(yōu)化:將原GFP_KERNEL改為false,適配RK平臺CMA內(nèi)存布局 page =cma_alloc(rk_heap->cma, size >> PAGE_SHIFT,0,false); if(!page) returnERR_PTR(-ENOMEM); // 后續(xù)內(nèi)存初始化邏輯... returndmabuf;}
代碼解析:調(diào)整cma_alloc的最后一個參數(shù)(從GFP_KERNEL改為false),優(yōu)化連續(xù)內(nèi)存分配策略,避免因內(nèi)存分配標志位不匹配導致的CMA內(nèi)存分配失敗,精準適配RK平臺的CMA內(nèi)存布局特點。
?新增模塊依賴聲明MODULE_IMPORT_NS(DMA_BUF),確保模塊加載時的依賴一致性,避免加載失敗。
// 新增模塊依賴聲明(核心代碼片段)MODULE_IMPORT_NS(DMA_BUF);// 導入DMA_BUF命名空間,確保依賴加載順序MODULE_LICENSE("GPL");MODULE_DESCRIPTION("RK CMA Heap for DMA-BUF");
代碼解析:通過MODULE_IMPORT_NS(DMA_BUF)聲明模塊依賴于DMA-BUF命名空間,確保內(nèi)核加載RK CMA堆模塊時,DMA-BUF核心模塊已提前加載,避免因依賴順序錯誤導致的模塊加載失敗。
2. RK系統(tǒng)堆升級(rk_system_heap.c)
?移除舊版延遲釋放邏輯,全面適配補丁新增的頁池管理機制,實現(xiàn)內(nèi)存頁的高效復用;
?kmap_local_pagekmap_atomic優(yōu)化內(nèi)存零填充實現(xiàn):用替代,減少內(nèi)核搶占沖突,提升多線程高頻內(nèi)存操作場景下的穩(wěn)定性;
// 內(nèi)存零填充優(yōu)化(核心代碼片段)staticvoidrk_system_heap_zero_page(structpage *page){ void*addr; // 用kmap_local_page替代kmap_atomic,減少內(nèi)核搶占沖突 addr =kmap_local_page(page); memset(addr,0, PAGE_SIZE);// 內(nèi)存零填充 kunmap_local(addr);// 對應釋放映射}
代碼解析:kmap_atomic會禁止內(nèi)核搶占,在多線程高頻內(nèi)存操作場景下易導致阻塞;替換為kmap_local_page,允許內(nèi)核搶占,同時保證內(nèi)存操作的安全性,提升RK平臺設備在多任務場景下的穩(wěn)定性。
?重構(gòu)內(nèi)存池大小統(tǒng)計邏輯,通過頁池管理的原生接口實現(xiàn)內(nèi)存占用的精準計算,提升監(jiān)控準確性;
?完善vmap/vunmap接口的錯誤處理,新增返回值與狀態(tài)清理邏輯,避免映射異常導致的內(nèi)存錯誤。
3.編譯配置模塊化調(diào)整
?DMABUF_HEAPS_DEFERRED_FREEDMABUF_HEAPS_PAGE_POOLKconfig中新增與配置項,支持兩大新組件的模塊化編譯,可根據(jù)設備資源規(guī)格靈活開啟/關(guān)閉,適配輕量與高性能的不同RK設備場景;
// Kconfig新增配置項(核心代碼片段)config DMABUF_HEAPS_DEFERRED_FREE bool"Deferred free helper for DMA-BUF heaps" dependsonDMABUF_HEAPS help Enable deferred free helperforDMA-BUF heaps, which supports asynchronous memory release to reduce fragmentation. (Recommendedforhigh-performance RK devices)config DMABUF_HEAPS_PAGE_POOL bool"Page pool support for DMA-BUF heaps" dependsonDMABUF_HEAPS help Enable page poolforDMA-BUF heaps, which pre-allocates memory pages to reduce allocation overhead. (RecommendedforAndroid devices)
代碼解析:新增兩個模塊化配置項,開發(fā)者可根據(jù)RK設備的資源規(guī)格(如內(nèi)存大小、性能需求)靈活選擇是否開啟延遲釋放和頁池管理組件;輕量設備可關(guān)閉以節(jié)省資源,高性能設備開啟以提升內(nèi)存操作效率。
?Makefile中調(diào)整系統(tǒng)堆、CMA堆的編譯目標命名,明確標識為RK平臺專屬版本,方便編譯管理與平臺區(qū)分。
#Makefile調(diào)整(核心代碼片段)obj-$(CONFIG_DMABUF_HEAPS_RK_CMA) += rk_cma_heap.oobj-$(CONFIG_DMABUF_HEAPS_RK_SYSTEM) += rk_system_heap.o#原命名為cma_heap.o、system_heap.o,新增rk_前綴,明確平臺專
代碼解析:將編譯目標命名從原有的cma_heap.o、system_heap.o改為rk_cma_heap.o、rk_system_heap.o,明確標識為RK平臺專屬版本,避免與其他平臺的堆模塊命名沖突,方便編譯管理與版本區(qū)分。
(五)細節(jié)優(yōu)化,提升整體穩(wěn)定性與性能
除核心功能與架構(gòu)改動外,補丁還在細節(jié)上進行了多處優(yōu)化,覆蓋同步邏輯、內(nèi)存對齊、錯誤處理等方面,進一步提升模塊的穩(wěn)定性與性能:
1.sysfs統(tǒng)計異步化:將DMA-BUF統(tǒng)計節(jié)點的創(chuàng)建從同步執(zhí)行改為工作隊列異步執(zhí)行,避免阻塞內(nèi)存分配主線程,提升高頻內(nèi)存申請場景下的響應速度;
// sysfs節(jié)點異步創(chuàng)建(核心代碼片段)staticvoiddma_buf_sysfs_init_work(struct work_struct *work) { dma_heap_sysfs_init();// 異步執(zhí)行sysfs節(jié)點初始化}// 初始化入口調(diào)整為異步intdma_buf_init(void) { INIT_WORK(&dma_buf_sysfs_work, dma_buf_sysfs_init_work); schedule_work(&dma_buf_sysfs_work);// 提交工作隊列,異步執(zhí)行 return0;}
代碼解析:將sysfs節(jié)點初始化邏輯放入工作隊列,異步執(zhí)行,避免同步初始化時阻塞DMA-BUF核心初始化流程,尤其在高頻內(nèi)存申請場景下,可提升系統(tǒng)響應速度。
2.強制頁面對齊:所有DMA-Heap的內(nèi)存分配均通過PAGE_ALIGN確保按頁對齊,避免因內(nèi)存對齊問題導致的硬件設備訪問異常,適配RK平臺的硬件訪問規(guī)范;
3.完善錯誤回滾:重構(gòu)dma_buf_export的錯誤處理邏輯,新增err_sysfs分支,確保sysfs節(jié)點創(chuàng)建失敗時能完整回滾已分配的文件、內(nèi)存等資源;
4.保障緩存一致性:在局部CPU訪問接口中增加柵欄等待邏輯,確保CPU與DMA設備的內(nèi)存視圖一致,避免數(shù)據(jù)不一致導致的程序異常;
5.精準參數(shù)校驗:在內(nèi)存分配接口中增加對fd_flags與heap_flags的參數(shù)校驗,拒絕非法參數(shù),提升接口的健壯性。
三、應用價值:三大維度賦能嵌入式生態(tài)
本次DMA-BUF補丁的改造,不僅實現(xiàn)了Android生態(tài)與RK平臺的雙向適配,更對嵌入式Linux的內(nèi)存管理生態(tài)提供了可復用的優(yōu)化方案,其應用價值覆蓋生態(tài)兼容、平臺性能、內(nèi)核技術(shù)三大維度:
1.對Android生態(tài):補全RK平臺的兼容性短板
補丁完美匹配Android系統(tǒng)對DMA-BUF的功能與接口要求,解決了RK平臺在Android生態(tài)下,圖形渲染、視頻編解碼、相機等核心多媒體模塊的內(nèi)存共享兼容性問題,為RK平臺設備運行高版本Android系統(tǒng)提供了關(guān)鍵的底層支撐。
2.對RK平臺:提升嵌入式設備核心競爭力
通過頁池復用、延遲釋放、局部內(nèi)存同步等優(yōu)化,RK平臺設備的內(nèi)存分配延遲、碎片率大幅降低,在機頂盒、工業(yè)平板、智能座艙、物聯(lián)網(wǎng)終端等嵌入式場景中,可顯著提升設備在高頻多媒體操作、多任務運行時的流暢度與穩(wěn)定性,強化平臺的市場競爭力。
3.對Linux內(nèi)核生態(tài):完善DMA-BUF技術(shù)方案
補丁新增的延遲釋放、頁池管理組件采用通用化設計,不依賴特定硬件平臺,可為其他嵌入式平臺的DMA-BUF優(yōu)化提供參考;而DMA-Heap的架構(gòu)升級與接口擴展,也為Linux內(nèi)核的內(nèi)存管理機制提供了更完善、更高效的實現(xiàn)方案,推動DMA-BUF生態(tài)的進一步發(fā)展。
四、總結(jié)
本次針對DMA-BUF的補丁改造,并非簡單的功能疊加,而是一次從底層基礎組件、核心對外接口、DMA-Heap架構(gòu)設計到RK平臺硬件適配的全鏈路升級。其設計思路圍繞“生態(tài)適配”與“高性能”兩大核心,既精準命中了Android系統(tǒng)對內(nèi)存管理的精細化要求,又深度挖掘了RK平臺的硬件潛力,同時通過通用化的組件設計為Linux內(nèi)核生態(tài)貢獻了可復用的技術(shù)方案。
在嵌入式設備對多媒體性能、多任務處理能力要求不斷提升的背景下,這套適配Android與RK特性的DMA-BUF內(nèi)存管理方案,將成為RK平臺嵌入式設備的核心技術(shù)支撐之一。同時,其底層的內(nèi)存優(yōu)化思路,也為其他嵌入式平臺的內(nèi)存管理調(diào)優(yōu)提供了極具價值的實踐參考,對推動嵌入式Linux與Android生態(tài)的技術(shù)發(fā)展具有積極意義。
審核編輯 黃宇
-
Android
+關(guān)注
關(guān)注
12文章
4031瀏覽量
134126 -
patch
+關(guān)注
關(guān)注
0文章
15瀏覽量
8553
發(fā)布評論請先 登錄
ADP5034:高性能電源管理芯片的深度解析
深度解析ADP5051:高性能集成電源解決方案
BUF12840:可編程伽馬電壓發(fā)生器的深度解析
RK平臺Android設備OTA升級教程:從原理到U盤實操
高性能電源利器:LTC7050 - 1深度解析
硬核進階:RK3576 Android15?驅(qū)動與系統(tǒng)開發(fā)實戰(zhàn)指南
深度解析?| DMA-BUF適配Android與RK特性核心Patch:高性能內(nèi)存管理升級方案
評論