常用記憶體配置設定函數
__get_free_pages
unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)
__get_free_pages函數是最原始的記憶體配置設定方式,直接從夥伴系統中擷取原始頁框,返
回值為第一個頁框的起始位址。__get_free_pages在實作上隻是封裝了alloc_pages函 數,
從代碼分析,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的記憶體時使核心崩潰。
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的空間。
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。