529
技術社區[雲棲]
Linux內核中常見內存分配函數(二)
常用內存分配函數
__get_free_pages
unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)
__get_free_pages函數是最原始的內存分配方式,直接從夥伴係統中獲取原始頁框,返
回值為第一個頁框的起始地址。__get_free_pages在實現上隻是封裝了alloc_pages函 數,Linux培訓
從代碼分析,alloc_pages函數會分配長度為1<
kmem_cache_alloc
struct kmem_cache *kmem_cache_create(const char *name, size_t size,
size_t align, unsigned long flags,
void (*ctor)(void*, struct kmem_cache *, unsigned long),
void (*dtor)(void*, struct kmem_cache *, unsigned long))
void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags)
kmem_cache_create/ kmem_cache_alloc是基於slab分配器的一種內存分配方式,適用於反複分配釋放同一大小內存塊的場合。首先用kmem_cache_create創建一個高速緩存區域,然後用kmem_cache_alloc從 該高速緩存區域中獲取新的內存塊。 kmem_cache_alloc一次能分配的最大內存由mm/slab.c文件中的MAX_OBJ_ORDER宏 定義,在默認的2.6.18內核版本中,該宏定義為5, 於是一次最多能申請1<<5 * 4KB也就是128KB的
連續物理內存。分析內核源碼發現,kmem_cache_create函數的size參數大於128KB時會調用BUG()。測試結果驗證了分析結果,用kmem_cache_create分 配超過128KB的內存時使內核崩潰。Linux培訓
kmalloc
void *kmalloc(size_t size, gfp_t flags)
kmalloc是內核中最常用的一種內存分配方式,它通過調用kmem_cache_alloc函 數來實現。kmalloc一次最多能申請的內存大小由include/linux/Kmalloc_size.h的 內容來決定,
在默認的2.6.18內核版本中,kmalloc一 次最多能申請大小為131702B也就是128KB字 節的連續物理內存。測試結果表明,如果試圖用kmalloc函數分配大於128KB的內存,編譯不能通過。
vmalloc
void *vmalloc(unsigned long size)
前麵幾種內存分配方式都是物理連續的,能保證較低的平均訪問時間。但是在某些場合
中,對內存區的請求不是很頻繁,較高的內存訪問時間也 可以接受,這是就可以分配一段線性連續,物理不連續的地址,帶來的好處是一次可以分配較大塊的內存。vmalloc對 一次能分配的內存大小沒有明確限製。出於性能考慮,應謹慎使用vmalloc函數。在測試過程中, 最大能一次分配1GB的空間。
Linux內核部分內存分布
dma_alloc_coherent
void *dma_alloc_coherent(struct device *dev, size_t size,
ma_addr_t *dma_handle, gfp_t gfp)
DMA是一種硬件機製,允許外圍設備和主存之間直接傳輸IO數據,而不需要CPU的參與,使用DMA機製能大幅提高與設備通信的 吞吐量。DMA操作中,涉及到CPU高速緩 存和對應的內存數據一致性的問題,必須保證兩者的數據一致,在x86_64體係結構中,硬件已經很 好的解決了這個問題, dma_alloc_coherent和__get_free_pages函數實現差別不大,前者實際是調用__alloc_pages函 數來分配內存,因此一次分配內存的大小限製和後者一樣。
__get_free_pages分配的內 存同樣可以用於DMA操作。測試結果證明,dma_alloc_coherent
函數一次能分配的最大內存也為4M。
最後更新:2017-04-03 16:48:51