linux驅動 linux塊裝置學習筆記(一)

2021-06-21 22:54:25 字數 2657 閱讀 8685

1,區別塊裝置和字元裝置:塊裝置是系統中能隨機訪問固定大小的資料片的硬體。

,扇區是所有塊裝置物理上的最小可定址單位,通常大小為512byte,塊是檔案系統的最小定址單位,大小是扇區的整數倍,同時不能超過乙個頁的大小~

操作塊裝置的時候需要在記憶體中有乙個對應的緩衝區,用struct buffer_head結構體表示。

struct buffer_head ;  

struct bio_vec ;

在2.6核心中,也既,將原來由buffer_head乙個結構來完成的工作,現在由buffer_head和bio共同來完成。現在,buffer_head只給上層提供有關其所描述的塊的當前狀態,而bio則負責將盡可能多的塊合併起來,傳遞給下層驅動程式,並最終寫入硬碟。也即,buffer_head負責描述

磁碟塊到物理記憶體的對映

,bio負責

所有塊i/o操作的容器

2,請求佇列

上層檔案系統如果要對底層的裝置資料讀寫的時候,它們首先會將它們的請求傳送到請求佇列中,該佇列由reques_queue結構體表示,包含

雙向請求鍊錶以及相關控制資訊,佇列中的具體的請求由struct request表示,每個請求又可以由多個bio結構體組成,

3,io排程程式

io排程程式試圖通過扇區將請求佇列合併排序,盡量使磁頭的請求順序是乙個方向,

為了優化塊裝置定址操作,io排程程式會在將請求提交給磁碟時,會先執行合併和排序的預操作,可以提高系統的整體效能。合併的含義是當兩次請求對於底層塊裝置請求的扇區臨近,那麼io排程程式會合併請求。排序的含義是使多次請求對底層塊裝置扇區的排列順序有序排列

2.4核心中採用的是linus電梯io排程程式,缺點是當某個磁碟區域上頻繁操作會使磁碟其他位置請求得不到執行機會,可能造成讀寫飢餓的情況發生為了改善linus電梯的缺點,後面有了最終期限io排程程式,

當乙個新請求加入i/o請求佇列時,linus電梯排程程式可能會發生以下4種操作:

如果佇列中已存在乙個對相鄰磁碟扇區操作的請求,那麼新請求將和這個已存在的請求合併成乙個請求

如果佇列中存在乙個駐留時間過長的請求,那麼新請求之間查到佇列尾部,防止舊的請求發生飢餓

如果佇列中已扇區方向為序存在合適的插入位置,那麼新請求將被插入該位置,保證佇列中的請求是以被訪問磁碟物理位置為序進行排列的

如果佇列中不存在合適的請求插入位置,請求將被插入到佇列尾部

最終期限io排程程式中每個請求都有乙個超時時間,預設讀請求的超時時間是500ms,寫請求的超時時間是5s,最終期限io排程除了維護乙個以磁碟扇區定址的排序佇列,還維護乙個fifo佇列,該排程程式缺點是降低系統吞吐量(而且讀寫請求的響應時間要求也是不一樣的,一般來說,寫請求的響應時間要求不高,寫請求可以和提交它的應用程式非同步執行,但是讀請求一般和提交它的應用程式時同步執行,應用程式等獲取到讀的資料後才會接著往下執行。)

乙個新請求加入到i/o請求佇列時,最終期限i/o排程和linus電梯排程相比,多出了以下操作:

1.新請求加入到 排序佇列(order-fifo),加入的方法類似 linus電梯新請求加入的方法

2.根據新請求的型別,將其加入 讀佇列(read-fifo) 或者寫佇列(wirte-fifo) 的尾部(讀寫佇列是按加入時間排序的,所以新請求都是加到尾部)

3.排程程式首先判斷 讀,寫佇列頭的請求是否超時,如果超時,從讀,寫佇列頭取出請求,加入到派發佇列(dispatch-fifo)

4.如果沒有超時請求,從 排序佇列(order-fifo)頭取出乙個請求加入到 派發佇列(dispatch-fifo)

5.派發佇列(dispatch-fifo)按順序將請求提交到磁碟驅動,完成i/o操作

**io排程程式,在最終期限io排程程式的基礎上,在每次處理讀請求的時候都會等待幾毫秒,預設為6ms

最終期限i/o排程演算法優先考慮讀請求的響應時間,但系統處於寫操作繁重的狀態時,會大大降低系統的吞吐量。 因為讀請求的超時時間比較短,所以每次有讀請求時,都會打斷寫請求,讓磁碟定址到讀的位置,完成讀操作後再回來繼續寫。 這種做法保證讀請求的響應速度,卻損害了系統的全域性吞吐量(磁頭先去讀再回來寫,發生了2次定址操作)

但有乙個新請求加入到i/o請求佇列時,**i/o排程與最終期限i/o排程相比,多了以下操作:

1.新的讀請求提交後,並不立即進行請求處理,而是有意等待片刻(預設是6ms)

2.等待期間如果有其他對磁碟相鄰位置進行讀操作的讀請求加入,會立刻處理這些讀請求

3.等待期間如果沒有其他讀請求加入,那麼等待時間相當於浪費掉

4.等待時間結束後,繼續執行以前剩下的請求

linux系統預設的io排程程式是完全公正排隊的io排程程式,cfq io排程程式把進入的io請求放入特定的佇列中,這種佇列根據引起io請求的程序組織,每個佇列後續再合併和排序操作,cfq io排程程式以時間片輪轉排程佇列,從每個佇列選取請求數,預設值是4

完全公正的排隊(complete fair queuing, cfq)i/o排程 是為專有工作負荷設計的,它和之前提到的i/o排程有根本的不同。

cfq i/o排程 演算法中,每個程序都有自己的i/o佇列,

cfq i/o排程程式以時間片輪轉排程佇列,從每個佇列中選取一定的請求數(預設4個),然後進行下一輪排程。

cfq i/o排程在程序級提供了公平,它的實現位於: block/cfq-iosched.c

Linux塊裝置驅動

塊裝置提供塊裝置提供裝置的訪問,裝置的訪問,可以隨機的以固定大小的塊傳輸資料,例如我們最為常見的磁碟裝置,當然塊裝置和字元裝置有較大差別,塊裝置有自己的驅動介面。簡單來說,核心決定乙個塊是固定的4096 位元組,當然該值可以隨著依賴檔案系統的變化而改變。塊裝置驅動採用register blkdev向...

linux驅動之塊裝置驅動

塊裝置驅動的系統架構 塊裝置註冊過程 1,註冊裝置塊驅動程式 register blkdev 2,初始化請求佇列 blk init queue 3,指明扇區的大小 blk queue logical block size dev queue,sect size 4,申請乙個gendisk結構,初始化...

LINUX塊裝置驅動 1

編寫塊裝置驅動的關鍵步驟 1 呼叫register blkdev申請或註冊主裝置號及裝置名稱,詳見核心原始碼中該函式的注釋。不過下面這篇文章裡並未用到這一步 2 呼叫blk init queue函式建立並初始化乙個 request queue 結構,該函式需要乙個用來處理請求的do request函...