Linux核心中常見記憶體配置函數(二)
來源:互聯網
上載者:User
常用記憶體配置函數 __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。