8.5. 獲得大量緩沖

2018-02-24 15:49 更新

8.5.?獲得大量緩沖

我們我們已經(jīng)在前面章節(jié)中注意到的, 大量連續(xù)內(nèi)存緩沖的分配是容易失敗的. 系統(tǒng)內(nèi)存長時間會碎片化, 并且常常出現(xiàn)一個真正的大內(nèi)存區(qū)會完全不可得. 因為常常有辦法不使用大緩沖來完成工作, 內(nèi)核開發(fā)者沒有優(yōu)先考慮使大分配能工作. 在你試圖獲得一個大內(nèi)存區(qū)之前, 你應(yīng)當真正考慮一下其他的選擇. 到目前止最好的進行大 I/O 操作的方法是通過發(fā)散/匯聚操作, 我們在第 1 章的"發(fā)散-匯聚 映射"一節(jié)中討論了.

8.5.1.?在啟動時獲得專用的緩沖

如果你真的需要一個大的物理上連續(xù)的緩沖, 最好的方法是在啟動時請求內(nèi)存來分配它. 在啟動時分配是獲得連續(xù)內(nèi)存頁而避開 __get_free_pages 施加的對緩沖大小限制的唯一方法, 不但最大允許大小還有限制的大小選擇. 在啟動時分配內(nèi)存是一個"臟"技術(shù), 因為它繞開了所有的內(nèi)存管理策略通過保留一個私有的內(nèi)存池. 這個技術(shù)是不優(yōu)雅和不靈活的, 但是它也是最不易失敗的. 不必說, 一個模塊無法在啟動時分配內(nèi)存; 只有直接連接到內(nèi)核的驅(qū)動可以這樣做.

啟動時分配的一個明顯問題是對通常的用戶它不是一個靈活的選擇, 因為這個機制只對連接到內(nèi)核映象中的代碼可用. 一個設(shè)備驅(qū)動使用這種分配方法可以被安裝或者替換只能通過重新建立內(nèi)核并且重啟計算機.

當內(nèi)核被啟動, 它贏得對系統(tǒng)種所有可用物理內(nèi)存的存取. 它接著初始化每個子系統(tǒng)通過調(diào)用子系統(tǒng)的初始化函數(shù), 允許初始化代碼通過減少留給正常系統(tǒng)操作使用的 RAM 數(shù)量, 來分配一個內(nèi)存緩沖給自己用.

啟動時內(nèi)存分配通過調(diào)用下面一個函數(shù)進行:


#include <linux/bootmem.h>
void *alloc_bootmem(unsigned long size);
void *alloc_bootmem_low(unsigned long size);
void *alloc_bootmem_pages(unsigned long size);
void *alloc_bootmem_low_pages(unsigned long size);

這些函數(shù)分配或者整個頁(如果它們以 _pages 結(jié)尾)或者非頁對齊的內(nèi)存區(qū). 分配的內(nèi)存可能是高端內(nèi)存除非使用一個 _low 版本. 如果你在為一個設(shè)備驅(qū)動分配這個緩沖, 你可能想用它做 DMA 操作, 并且這對于高端內(nèi)存不是一直可能的; 因此, 你可能想使用一個 _low 變體.

很少在啟動時釋放分配的內(nèi)存; 你會幾乎肯定不能之后取回它, 如果你需要它. 但是, 有一個接口釋放這個內(nèi)存:


void free_bootmem(unsigned long addr, unsigned long size); 

注意以這個方式釋放的部分頁不返回給系統(tǒng) -- 但是, 如果你在使用這個技術(shù), 你已可能分配了不少數(shù)量的整頁來用.

如果你必須使用啟動時分配, 你需要直接連接你的驅(qū)動到內(nèi)核. 應(yīng)當如何完成的更多信息看在內(nèi)核源碼中 Documentation/kbuild 下的文件.

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號