kmalloc/kfree,vmalloc/vfree函数用法和区别
kmalloc/kfree,vmalloc/vfree函數(shù)用法和區(qū)別
1.kmalloc
1>kmalloc內(nèi)存分配和malloc相似,除非被阻塞否則他執(zhí)行的速度非常快,而且不對(duì)獲得空間清零.
<?
tiger說明:在用kmalloc申請(qǐng)函數(shù)后,要對(duì)起清零
用memset()函數(shù)對(duì)申請(qǐng)的內(nèi)存進(jìn)行清零。
>?
2>kamlloc函數(shù)原型:
#include<linux/slab.h>
Void *kmalloc(size_t size, int flags);
(1)第一個(gè)參數(shù)是要分配的塊的大小
(2)第二個(gè)參數(shù)是分配標(biāo)志(flags),他提供了多種kmalloc的行為。
(3)第三個(gè)最常用的GFP_KERNEL;
A.表示內(nèi)存分配(最終總是調(diào)用get_free_pages來(lái)實(shí)現(xiàn)實(shí)際的分配;這就是GFP前綴的由來(lái))是代表運(yùn)行在內(nèi)核空間的進(jìn)程執(zhí)行的。使用GFP_KERNEL容許kmalloc在分配空閑內(nèi)存時(shí)候如果內(nèi)存不足容許把當(dāng)前進(jìn)程睡眠以等待。因此這時(shí)分配函數(shù)必須是可重入的。如果在進(jìn)程上下文之外如:中斷處理程序、tasklet以及內(nèi)核定時(shí)器中這種情況下current進(jìn)程不該睡眠,驅(qū)動(dòng)程序該使用GFP_ATOMIC.
B.GFP_ATOMIC
用來(lái)從中斷處理和進(jìn)程上下文之外的其他代碼中分配內(nèi)存.?從不睡眠.
C.GFP_KERNEL
內(nèi)核內(nèi)存的正常分配.?可能睡眠.
D.GFP_USER
用來(lái)為用戶空間頁(yè)來(lái)分配內(nèi)存;?它可能睡眠.
E.GFP_HIGHUSER
如同?GFP_USER,?但是從高端內(nèi)存分配,?如果有.?高端內(nèi)存在下一個(gè)子節(jié)描述.
F.GFP_NOFS,GFP_NOIO
這個(gè)標(biāo)志功能如同?GFP_KERNEL,?但是它們?cè)黾酉拗频絻?nèi)核能做的來(lái)滿足請(qǐng)求.一個(gè)?GFP_NOFS?分配不允許進(jìn)行任何文件系統(tǒng)調(diào)用,?而?GFP_NOIO?根本不允許任何?I/O?初始化.?它們主要地用在文件系統(tǒng)和虛擬內(nèi)存代碼,?那里允許一個(gè)分配睡眠,?但是遞歸的文件系統(tǒng)調(diào)用會(huì)是一個(gè)壞注意.
上面列出的這些分配標(biāo)志可以是下列標(biāo)志的相或來(lái)作為參數(shù),?這些標(biāo)志改變這些分配如何進(jìn)行:
__GFP_DMA
這個(gè)標(biāo)志要求分配在能夠?DMA?的內(nèi)存區(qū).?確切的含義是平臺(tái)依賴的并且在下面章節(jié)來(lái)解釋.
__GFP_HIGHMEM
這個(gè)標(biāo)志指示分配的內(nèi)存可以位于高端內(nèi)存.
__GFP_COLD
正常地,?內(nèi)存分配器盡力返回"緩沖熱"的頁(yè)?--?可能在處理器緩沖中找到的頁(yè).?相反,?這個(gè)標(biāo)志請(qǐng)求一個(gè)"冷"頁(yè),?它在一段時(shí)間沒被使用.?它對(duì)分配頁(yè)作?DMA?讀是有用的,?此時(shí)在處理器緩沖中出現(xiàn)是無(wú)用的.?一個(gè)完整的對(duì)如何分配?DMA?緩存的討論看"直接內(nèi)存存取"一節(jié)在第?1?章.
__GFP_NOWARN
這個(gè)很少用到的標(biāo)志阻止內(nèi)核來(lái)發(fā)出警告(使用?printk ),?當(dāng)一個(gè)分配無(wú)法滿足.
__GFP_HIGH
這個(gè)標(biāo)志標(biāo)識(shí)了一個(gè)高優(yōu)先級(jí)請(qǐng)求,?它被允許來(lái)消耗甚至被內(nèi)核保留給緊急狀況的最后的內(nèi)存頁(yè).
???__GFP_REPEAT
__GFP_NOFAIL
__GFP_NORETRY
這些標(biāo)志修改分配器如何動(dòng)作,?當(dāng)它有困難滿足一個(gè)分配. __GFP_REPEAT?意思是"?更盡力些嘗試"?通過重復(fù)嘗試?--?但是分配可能仍然失敗. __GFP_NOFAIL?標(biāo)志告訴分配器不要失敗;?它盡最大努力來(lái)滿足要求.?使用?__GFP_NOFAIL?是強(qiáng)烈不推薦的;?可能從不會(huì)有有效的理由在一個(gè)設(shè)備驅(qū)動(dòng)中使用它.?最后, __GFP_NORETRY?告知分配器立即放棄如果得不到請(qǐng)求的內(nèi)存.
???內(nèi)存區(qū)段
__GFP_DMA和__GFP_HIGHMEM的使用與平臺(tái)相關(guān),Linux把內(nèi)存分成3個(gè)區(qū)段:可用于DMA的內(nèi)存、常規(guī)內(nèi)存、以及高端內(nèi)存。X86平臺(tái)上ISA設(shè)備DMA區(qū)段是內(nèi)存的前16MB,而PCI設(shè)備無(wú)此限制。
內(nèi)存區(qū)后面的機(jī)制在?mm/page_alloc.c?中實(shí)現(xiàn),?而內(nèi)存區(qū)的初始化在平臺(tái)特定的文件中,?常常在?arch?目錄樹的?mm/init.c。
3>kamlloc的使用方法:
Linux?處理內(nèi)存分配通過創(chuàng)建一套固定大小的內(nèi)存對(duì)象池.?分配請(qǐng)求被這樣來(lái)處理,?進(jìn)入一個(gè)持有足夠大的對(duì)象的池子并且將整個(gè)內(nèi)存塊遞交給請(qǐng)求者.?驅(qū)動(dòng)開發(fā)者應(yīng)當(dāng)記住的一件事情是,?內(nèi)核只能分配某些預(yù)定義的,?固定大小的字節(jié)數(shù)組.
如果你請(qǐng)求一個(gè)任意數(shù)量?jī)?nèi)存,?你可能得到稍微多于你請(qǐng)求的,?至多是?2?倍數(shù)量.?同樣,?程序員應(yīng)當(dāng)記住?kmalloc?能夠處理的最小分配是?32?或者?64?字節(jié),?依賴系統(tǒng)的體系所使用的頁(yè)大小. kmalloc?能夠分配的內(nèi)存塊的大小有一個(gè)上限.這個(gè)限制隨著體系和內(nèi)核配置選項(xiàng)而變化.?如果你的代碼是要完全可移植,?它不能指望可以分配任何大于?128 KB.?如果你需要多于幾個(gè)?KB,?但是,?有個(gè)比kmalloc?更好的方法來(lái)獲得內(nèi)存。在設(shè)備驅(qū)動(dòng)程序或者內(nèi)核模塊中動(dòng)態(tài)開辟內(nèi)存,不是用malloc,而是kmalloc ,vmalloc,或者用get_free_pages直接申請(qǐng)頁(yè)。釋放內(nèi)存用的是kfree,vfree,或free_pages. kmalloc函數(shù)返回的是虛擬地址(線性地址). kmalloc特殊之處在于它分配的內(nèi)存是物理上連續(xù)的,這對(duì)于要進(jìn)行DMA的設(shè)備十分重要.?而用vmalloc分配的內(nèi)存只是線性地址連續(xù),物理地址不一定連續(xù),不能直接用于DMA.
注意kmalloc最大只能開辟128k-16,16個(gè)字節(jié)是被頁(yè)描述符結(jié)構(gòu)占用了。kmalloc用法參見khg.
內(nèi)存映射的I/O口,寄存器或者是硬件設(shè)備的RAM(如顯存)一般占用F0000000以上的地址空間。在驅(qū)動(dòng)程序中不能直接訪問,要通過kernel函數(shù)vremap獲得重新映射以后的地址。
另外,很多硬件需要一塊比較大的連續(xù)內(nèi)存用作DMA傳送。這塊內(nèi)存需要一直駐留在內(nèi)存,不能被交換到文件中去。但是kmalloc最多只能開辟大小為32XPAGE_SIZE的內(nèi)存,一般的PAGE_SIZE=4kB,也就是128kB的大小的內(nèi)存。
3.kmalloc和vmalloc的區(qū)別
??vmalloc()與?kmalloc()都可用于分配內(nèi)存
??kmalloc()分配的內(nèi)存處于3GB~high_memory之?間,這段內(nèi)核空間與物理內(nèi)存的映射一一對(duì)應(yīng)
?vmalloc()分配的內(nèi)存在?VMALLOC_START~4GB之間,這段非連續(xù)內(nèi)?存區(qū)映射到物理內(nèi)存也可能是非連續(xù)的
??在內(nèi)核空間中調(diào)用kmalloc()分配連續(xù)物理空間,而調(diào)用vmalloc()分配非物理連續(xù)空間。
??把kmalloc()所分配內(nèi)核空間中的地址稱為內(nèi)核邏輯地址
??把vmalloc()分配的內(nèi)核空間中的地址稱?為內(nèi)核虛擬地址
??vmalloc()在分配過程中須更新內(nèi)核頁(yè)表
總結(jié):
1.kmalloc和vmalloc分配的是內(nèi)核的內(nèi)存,malloc分配的是用戶的內(nèi)存
2.kmalloc保證分配的內(nèi)存在物理上是連續(xù)的, kmalloc()分配的內(nèi)存在0xBFFFFFFF-0xFFFFFFFF以上的內(nèi)存中,driver一般是用它來(lái)完成對(duì)DS的分配,更適合于類似設(shè)備驅(qū)動(dòng)的程序來(lái)使用;
3.vmalloc保證的是在虛擬地址空間上的連續(xù),vmalloc()則是位于物理地址非連續(xù),虛地址連續(xù)區(qū),起始位置由VMALLOL_START來(lái)決定,一般作為交換區(qū)、模塊的分配。
3.kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相對(duì)較大(因?yàn)関malloc還可以處理交換空間)。
4.內(nèi)存只有在要被DMA訪問的時(shí)候才需要物理上連續(xù),vmalloc比kmalloc要慢
5.vmalloc使用的正確場(chǎng)合是分配一大塊,連續(xù)的,只在軟件中存在的,用于緩沖的內(nèi)存區(qū)域。不能在微處理器之外使用。
6.vmalloc?中調(diào)用了?kmalloc?(GFP—KERNEL),因此也不能應(yīng)用于原子上下文。
7.kmalloc和?kfree管理內(nèi)核段內(nèi)分配的內(nèi)存,這是真實(shí)地址已知的實(shí)際物理內(nèi)存塊。
8.vmalloc對(duì)應(yīng)于vfree,分配連續(xù)的虛擬內(nèi)存,但是物理上不一定連續(xù)。
9.kmalloc分配內(nèi)存是基于slab,因此slab的一些特性包括著色,對(duì)齊等都具備,性能較好。物理地址和邏輯地址都是連續(xù)的
總結(jié)
以上是生活随笔為你收集整理的kmalloc/kfree,vmalloc/vfree函数用法和区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 死锁产生的4个必要条件,如何检测,解除死
- 下一篇: vmalloc 实现