|
這個函數(shù)就是原來的兩個函數(shù)的整合 , 即原來我們每次申請內(nèi)存的時候都會這么做 , 先是用 kmalloc() 申請空間 , 然后用 memset() 來初始化, 而現(xiàn)在省事了 , 一步到位 , 直接調(diào)用 kzalloc(), 效果等同于原來那兩個函數(shù) , 所有申請的元素都被初始化為 0. 其實(shí)對寫驅(qū)動的來說 , 知道現(xiàn)在應(yīng)該用kzalloc() 代替原來的 kmalloc() 和 memset() 就可以了 , 這是內(nèi)核中內(nèi)存管理部分做出的改變 , 確切的說是改進(jìn) , 負(fù)責(zé)內(nèi)存管理那部分的兄弟們的目標(biāo)無非就是讓內(nèi)核跑起來更快一些 , 而從 kmalloc/memset 到 kzalloc 的改變確實(shí)也是為了實(shí)現(xiàn)這方面的優(yōu)化。 kmalloc 原型是: #include <linux/slab.h> void *kmalloc(size_t size, int flags); 給 kmalloc 的第一個參數(shù)是要分配的塊的大小. 第 2 個參數(shù), 分配標(biāo)志, 非常有趣, 因為它以幾個方式控制 kmalloc 的行為. 最一般使用的標(biāo)志, GFP_KERNEL, 意思是這個分配((內(nèi)部最終通過調(diào)用 __get_free_pages 來進(jìn)行, 它是 GFP_ 前綴的來源)代表運(yùn)行在內(nèi)核空間的進(jìn)程而進(jìn)行的. 換句話說, 這意味著調(diào)用函數(shù)是代表一個進(jìn)程在執(zhí)行一個系統(tǒng)調(diào)用. 使用 GFP_KENRL 意味著 kmalloc 能夠使當(dāng)前進(jìn)程在少內(nèi)存的情況下睡眠來等待一頁. 一個使用 GFP_KERNEL 來分配內(nèi)存的函數(shù)必須, 因此, 是可重入的并且不能在原子上下文中運(yùn)行. 當(dāng)當(dāng)前進(jìn)程睡眠, 內(nèi)核采取正確的動作來定位一些空閑內(nèi)存, 或者通過刷新緩存到磁盤或者交換出去一個用戶進(jìn)程的內(nèi)存. GFP_KERNEL 不一直是使用的正確分配標(biāo)志; 有時 kmalloc 從一個進(jìn)程的上下文的外部調(diào)用. 例如, 這類的調(diào)用可能發(fā)生在中斷處理, tasklet, 和內(nèi)核定時器中. 在這個情況下, 當(dāng)前進(jìn)程不應(yīng)當(dāng)被置為睡眠, 并且驅(qū)動應(yīng)當(dāng)使用一個 GFP_ATOMIC 標(biāo)志來代替. 內(nèi)核正常地試圖保持一些空閑頁以便來滿足原子的分配. 當(dāng)使用 GFP_ATOMIC 時, kmalloc 能夠使用甚至最后一個空閑頁. 如果這最后一個空閑頁不存在, 但是, 分配失敗. 其他用來代替或者增添 GFP_KERNEL 和 GFP_ATOMIC 的標(biāo)志, 盡管它們 2 個涵蓋大部分設(shè)備驅(qū)動的需要. 所有的標(biāo)志定義在<linux/gfp.h>, 并且每個標(biāo)志用一個雙下劃線做前綴, 例如 __GFP_DMA. 另外, 有符號代表常常使用的標(biāo)志組合; 這些缺乏前綴并且有時被稱為分配優(yōu)先級. 后者包括: GFP_ATOMIC 用來從中斷處理和進(jìn)程上下文之外的其他代碼中分配內(nèi)存. 從不睡眠. GFP_KERNEL 內(nèi)核內(nèi)存的正常分配. 可能睡眠. GFP_USER 用來為用戶空間頁來分配內(nèi)存; 它可能睡眠. GFP_HIGHUSER 如同 GFP_USER, 但是從高端內(nèi)存分配, 如果有. 高端內(nèi)存在下一個子節(jié)描述. GFP_NOIO GFP_NOFS 這個標(biāo)志功能如同 GFP_KERNEL, 但是它們增加限制到內(nèi)核能做的來滿足請求. 一個 GFP_NOFS 分配不允許進(jìn)行任何文件系統(tǒng)調(diào)用, 而 GFP_NOIO 根本不允許任何 I/O 初始化. 它們主要地用在文件系統(tǒng)和虛擬內(nèi)存代碼, 那里允許一個分配睡眠, 但是遞歸的文件系統(tǒng)調(diào)用會是一個壞注意. 上面列出的這些分配標(biāo)志可以是下列標(biāo)志的相或來作為參數(shù), 這些標(biāo)志改變這些分配如何進(jìn)行: __GFP_DMA 這個標(biāo)志要求分配在能夠 DMA 的內(nèi)存區(qū). 確切的含義是平臺依賴的并且在下面章節(jié)來解釋. __GFP_HIGHMEM 這個標(biāo)志指示分配的內(nèi)存可以位于高端內(nèi)存. __GFP_COLD 正常地, 內(nèi)存分配器盡力返回"緩沖熱"的頁 -- 可能在處理器緩沖中找到的頁. 相反, 這個標(biāo)志請求一個"冷"頁, 它在一段時間沒被使用. 它對分配頁作 DMA 讀是有用的, 此時在處理器緩沖中出現(xiàn)是無用的. 一個完整的對如何分配 DMA緩存的討論看"直接內(nèi)存存取"一節(jié)在第 1 章. __GFP_NOWARN 這個很少用到的標(biāo)志阻止內(nèi)核來發(fā)出警告(使用 printk ), 當(dāng)一個分配無法滿足. __GFP_HIGH 這個標(biāo)志標(biāo)識了一個高優(yōu)先級請求, 它被允許來消耗甚至被內(nèi)核保留給緊急狀況的最后的內(nèi)存頁. __GFP_REPEAT __GFP_NOFAIL __GFP_NORETRY 這些標(biāo)志修改分配器如何動作, 當(dāng)它有困難滿足一個分配. __GFP_REPEAT 意思是" 更盡力些嘗試" 通過重復(fù)嘗試 -- 但是分配可能仍然失敗. __GFP_NOFAIL 標(biāo)志告訴分配器不要失敗; 它盡最大努力來滿足要求. 使用 __GFP_NOFAIL 是強(qiáng)烈不推薦的; 可能從不會有有效的理由在一個設(shè)備驅(qū)動中使用它. 最后, __GFP_NORETRY 告知分配器立即放棄如果得不到請求的內(nèi)存. |
|
|