kmalloc/kfree,vmalloc/vfree函數用法和區別linux
1.kmalloc程序員
1>kmalloc內存分配和malloc類似,除非被阻塞不然他執行的速度很是快,並且不對得到空間清零.數組
< 緩存
tiger說明:在用kmalloc申請函數後,要對起清零函數
用memset()函數對申請的內存進行清零。性能
> 對象
2>kamlloc函數原型:遞歸
#include<linux/slab.h>進程
Void *kmalloc(size_t size, int flags);內存
(1)第一個參數是要分配的塊的大小
(2)第二個參數是分配標誌(flags),他提供了多種kmalloc的行爲。
(3)第三個最經常使用的GFP_KERNEL;
A.表示內存分配(最終老是調用get_free_pages來實現實際的分配;這就是GFP前綴的由來)是表明運行在內核空間的進程執行的。使用GFP_KERNEL允許kmalloc在分配空閒內存時候若是內存不足允許把當前進程睡眠以等待。所以這時分配函數必須是可重入的。若是在進程上下文以外如:中斷處理程序、tasklet以及內核定時器中這種狀況下current進程不應睡眠,驅動程序該使用GFP_ATOMIC.
B.GFP_ATOMIC
用來從中斷處理和進程上下文以外的其餘代碼中分配內存. 從不睡眠.
C.GFP_KERNEL
內核內存的正常分配. 可能睡眠.
D.GFP_USER
用來爲用戶空間頁來分配內存; 它可能睡眠.
E.GFP_HIGHUSER
如同 GFP_USER, 可是從高端內存分配, 若是有. 高端內存在下一個子節描述.
F.GFP_NOFS,GFP_NOIO
這個標誌功能如同 GFP_KERNEL, 可是它們增長限制到內核能作的來知足請求. 一個 GFP_NOFS 分配不容許進行任何文件系統調用, 而 GFP_NOIO 根本不容許任何 I/O 初始化. 它們主要地用在文件系統和虛擬內存代碼, 那裏容許一個分配睡眠, 可是遞歸的文件系統調用會是一個壞注意.
上面列出的這些分配標誌能夠是下列標誌的相或來做爲參數, 這些標誌改變這些分配如何進行:
__GFP_DMA
這個標誌要求分配在可以 DMA 的內存區. 確切的含義是平臺依賴的而且在下面章節來解釋.
__GFP_HIGHMEM
這個標誌指示分配的內存能夠位於高端內存.
__GFP_COLD
正常地, 內存分配器盡力返回"緩衝熱"的頁 -- 可能在處理器緩衝中找到的頁. 相反, 這個標誌請求一個"冷"頁, 它在一段時間沒被使用. 它對分配頁做 DMA 讀是有用的, 此時在處理器緩衝中出現是無用的. 一個完整的對如何分配 DMA 緩存的討論看"直接內存存取"一節在第 1 章.
__GFP_NOWARN
這個不多用到的標誌阻止內核來發出警告(使用 printk ), 當一個分配沒法知足.
__GFP_HIGH
這個標誌標識了一個高優先級請求, 它被容許來消耗甚至被內核保留給緊急情況的最後的內存頁.
__GFP_NOFAIL
__GFP_NORETRY
這些標誌修改分配器如何動做, 當它有困難知足一個分配. __GFP_REPEAT 意思是" 更盡力些嘗試" 經過重複嘗試 -- 可是分配可能仍然失敗. __GFP_NOFAIL 標誌告訴分配器不要失敗; 它盡最大努力來知足要求. 使用__GFP_NOFAIL 是強烈不推薦的; 可能從不會有有效的理由在一個設備驅動中使用它. 最後, __GFP_NORETRY告知分配器當即放棄若是得不到請求的內存.
__GFP_DMA和__GFP_HIGHMEM的使用與平臺相關,Linux把內存分紅3個區段:可用於DMA的內存、常規內存、以及高端內存。X86平臺上ISA設備DMA區段是內存的前16MB,而PCI設備無此限制。
內存區後面的機制在 mm/page_alloc.c 中實現, 而內存區的初始化在平臺特定的文件中, 經常在 arch 目錄樹的 mm/init.c。
3>kamlloc的使用方法:
Linux 處理內存分配經過建立一套固定大小的內存對象池. 分配請求被這樣來處理, 進入一個持有足夠大的對象的池子而且將整個內存塊遞交給請求者. 驅動開發者應當記住的一件事情是, 內核只能分配某些預約義的, 固定大小的字節數組.
若是你請求一個任意數量內存, 你可能獲得稍微多於你請求的, 至可能是 2 倍數量. 一樣, 程序員應當記住kmalloc 可以處理的最小分配是 32 或者 64 字節, 依賴系統的體系所使用的頁大小. kmalloc 可以分配的內存塊的大小有一個上限. 這個限制隨着體系和內核配置選項而變化. 若是你的代碼是要徹底可移植, 它不能期望能夠分配任何大於 128 KB. 若是你須要多於幾個 KB, 可是, 有個比 kmalloc 更好的方法來得到內存。在設備驅動程序或者內核模塊中動態開闢內存,不是用malloc,而是kmalloc ,vmalloc,或者用get_free_pages直接申請頁。釋放內存用的是kfree,vfree,或free_pages. kmalloc函數返回的是虛擬地址(線性地址). kmalloc特殊之處在於它分配的內存是物理上連續的,這對於要進行DMA的設備十分重要. 而用vmalloc分配的內存只是線性地址連續,物理地址不必定連續,不能直接用於DMA.
注意kmalloc最大隻能開闢128k-16,16個字節是被頁描述符結構佔用了。kmalloc用法參見khg.
內存映射的I/O口,寄存器或者是硬件設備的RAM(如顯存)通常佔用F0000000以上的地址空間。在驅動程序中不能直接訪問,要經過kernel函數vremap得到從新映射之後的地址。
另外,不少硬件須要一塊比較大的連續內存用做DMA傳送。這塊內存須要一直駐留在內存,不能被交換到文件中去。可是kmalloc最多隻能開闢大小爲32XPAGE_SIZE的內存,通常的PAGE_SIZE=4kB,也就是128kB的大小的內存。
3.kmalloc和vmalloc的區別
• vmalloc()與 kmalloc()均可用於分配內存
• kmalloc()分配的內存處於3GB~high_memory之 間,這段內核空間與物理內存的映射一一對應
•vmalloc()分配的內存在 VMALLOC_START~4GB之間,這段非連續內 存區映射到物理內存也多是非連續的
• 在內核空間中調用kmalloc()分配連續物理空間,而調用vmalloc()分配非物理連續空間。
• 把kmalloc()所分配內核空間中的地址稱爲內核邏輯地址
• 把vmalloc()分配的內核空間中的地址稱 爲內核虛擬地址
• vmalloc()在分配過程當中須更新內核頁表
總結:
1.kmalloc和vmalloc分配的是內核的內存,malloc分配的是用戶的內存
2.kmalloc保證分配的內存在物理上是連續的, kmalloc()分配的內存在0xBFFFFFFF-0xFFFFFFFF以上的內存中,driver通常是用它來完成對DS的分配,更適合於相似設備驅動的程序來使用;
3.vmalloc保證的是在虛擬地址空間上的連續,vmalloc()則是位於物理地址非連續,虛地址連續區,起始位置由VMALLOL_START來決定,通常做爲交換區、模塊的分配。
3.kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相對較大(由於vmalloc還能夠處理交換空間)。
4.內存只有在要被DMA訪問的時候才須要物理上連續,vmalloc比kmalloc要慢
5.vmalloc使用的正確場合是分配一大塊,連續的,只在軟件中存在的,用於緩衝的內存區域。不能在微處理器以外使用。
6.vmalloc 中調用了 kmalloc (GFP—KERNEL),所以也不能應用於原子上下文。
7.kmalloc和 kfree管理內核段內分配的內存,這是真實地址已知的實際物理內存塊。
8.vmalloc對應於vfree,分配連續的虛擬內存,可是物理上不必定連續。
9.kmalloc分配內存是基於slab,所以slab的一些特性包括着色,對齊等都具有,性能較好。物理地址和邏輯地址都是連續的