linux io
排程程式是塊裝置
i/o子系統的主要元件,它介於通用塊層和塊裝置驅動程式之間,所圖
2-1所示。當
linux
核心元件要讀寫一些資料時,並不是請求一發出,核心便立即執行該請求,而是將其推遲執行。延遲的設定是塊裝置效能的關鍵機制!當傳輸乙個新資料塊時,核心檢查能否通過擴充套件前乙個一直處於等待狀態的請求而滿足新請求。
圖 io
排程層所在系統中的位置
在2.6
核心中,核心中實現了四種
io排程演算法,分別為預期
(anticipatory)
演算法、最後期限
(deadline)
演算法、完全公平佇列
(cfq)
演算法以及
noop
演算法(no operation)
。可以在核心引導式指定一種
i/o排程演算法,也可以在執行時通過
sysfs
檔案系統
/sys/block/sda/queue/scheduler
來為塊裝置定製乙個特定的
i/o排程演算法或檢視塊裝置目前所使用的何種
io排程演算法。
由於linux io
排程程式是介於通用塊層和塊裝置驅動程式之間,所以它接收來自通用塊層的請求,試圖合併請求,並找到最合適的請求下發到塊裝置驅動程式中。之後塊裝置驅動程式會呼叫乙個策略函式來相應這個請求。這個策略函式是由裝置型別來決定的,例如,如果裝置是
scsi
硬碟,那麼
scsi
匯流排層便將
scsi_request_fn
註冊到該策略函式中。
在linux2.6.21
的核心源**中,用於實現
io排程程式的檔案有:
檔案路徑
描述/include/linux/elevator.h
定義了排程演算法一些公用的資料結構以及操作函式介面
/block/elevator.c 實現
elevator.h
中宣告的一些函式
/block/noop-iosched.c
用於實現
noop
演算法/block/as-iosched.c
用於實現預期演算法
/block/deadline-iosched.c
用於實現最後期限演算法
/block/cfq-iosched.c
用於實現完全公平佇列演算法
在elevator.h
中定義了一些重要的資料結構,包括
elevator_ops
,elevator_type
以及elevator_queue。ø
elevator_ops
定義了一些操作函式介面,這些介面函式由不同的
io排程演算法過載,下面是該資料結構中一些主要欄位的意義:
字段型別
描述elevator_merge_fn
elevator_merge_fn * 將
bio合併到合適的
request
中(準確地說,插入到
request
鍊錶的首部)
elevator_merged_fn
elevator_merged_fn *
執行插入
bio之後的一些附加操作
elevator_merge_req_fn
elevator_merge_req_fn*
合併兩個
request
操作elevator_allow_merge_fn
elevator_allow_merge_fn* 判斷
bio是否允許合併到
request
中elevator_dispatch_fn
elevator_dispatch_fn*
在佇列中取出最合適的
request
elevator_add_req_fn
elevator_add_req_fn*
向佇列中插入乙個新的
request
elevator_queue_empty_fn
elevator_queue_empty_fn*
判斷佇列是否為空
elevator_completed_req_fn
elevator_completed_req_fn*
請求完成時進行的一些操作
elevator_former_req_fn
elevator_request_list_fn*
取前乙個
request
操作elevator_latter_req_fn
elevator_request_list_fn*
取後乙個
request
操作elevator_init_fn
elevator_init_fn*
初始化操作
elevator_exit_fn
elevator_exit_fn*
退出操作
øelevator_type
結構用於描述排程的種類,其中主要字段描述如下:
字段型別
描述ops
struct elevator_ops
實現該排程演算法函式操作
elevator_attrs
struct elv_fs_entry *
sys介面elevator_name
char *
該排程演算法的名稱
øelevator_queue
結構描述了該塊裝置驅動使用何種
io排程演算法。通常每個物理塊裝置都自己維護乙個請求佇列,每個請求佇列上單獨執行
i/o排程。在請求對列中有乙個字段
elevator,
它的型別指向
sturct elevator_queue
的指標。
elevator_queue
結構如下:
struct elevator_queue ;
欄位ops定義了排程演算法的所有可能的操作:鏈結和斷開
elevator
,增加和合併佇列中的請求,從佇列中刪除請求,獲得佇列中下乙個待處理的請求等等。
欄位是elevator_type
,它是指向
struct elevator_type
型別的指標,它描述了塊裝置所使用
io排程演算法。
欄位hash
包含了處理請求佇列所需的所有資訊,通過這個雜湊表可以快速索引我們需要的某個
request。字段
elevator_data
用於描述
io排程程式用來處理請求的附加資料結構,如果使用
deadline
演算法,elevator_data
指向struct deadline_data
結構。按照我的理解,
elevator.h
定義了乙個框架,它類似物件導向程式中的基類,每個具體的
io排程程式可以看作是它的派生類。父類
elevator
中定義了一些公用的方法,而這些方法的實現依據不同的排程演算法其實現的方式也不同。子類會實現父類
elevator
中定義的函式集
elevator_ops
。下一節以
deadline
演算法為例來描述
io排程程式是如何處理來自通用塊層的請求,並最終下發到物理裝置上。
Linux IO排程層分析 2
deadline 演算法維護 5個佇列,除了請求佇列以外,演算法還使用了四個佇列。其中兩個排序佇列分別包含讀請求和寫請求,這個佇列是按照起始扇區數來排序的。另外兩個最後期限佇列包含相同的讀和寫請求,只不過它們是根據其 最後期限 排序的。這兩個佇列的目的是為了避免請求餓死。因為電梯策略優先處理與上乙個...
Linux I O排程策略
i o scheduler的作用就是為請求佇列裡面的io請求做乙個優化,以此達到提高系統吞吐量 縮短響應時間的目的。更改i o scheduler有兩種方式 1.sys block device name queue scheduler ioscheduler sys block device na...
修改Linux IO排程器
linux系統預設提供了三種io排程方式 原來系統中預設的排程方式是deadline,下面介紹如何更改預設排程機制。通過host cat sys block sdb queue scheduler sdb是我的系統安裝磁碟 noop deadline cfqhost 可以看到預設的排程方式是dead...