Linux Block模塊之deadline調度算法代碼解析( 二 )

3.4 合并后處理合并后 , 調用 deadline_merged_requests() 做合并后的處理
static voiddeadline_merged_requests(struct request_queue *q, struct request *req,struct request *next){ if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) {/* 如果next的期限小于req */if (time_before(next->fifo_time, req->fifo_time)) {/* 這個queuelist實際上就是真正發給設備驅動程序的隊列,處理完了的隊列 */list_move(&req->queuelist, &next->queuelist);/* 因為是next比req要先響應,合并完了肯定要以先響應的為準 */req->fifo_time = next->fifo_time;} } /* 從fifo_list和sort_list刪除next */ deadline_remove_request(q, next);}3.5 派發最后,調用 deadline_dispatch_requests() 將請求派發到系統的 request_queue 隊列中
static int deadline_dispatch_requests(struct request_queue *q, int force){ struct deadline_data *dd = q->elevator->elevator_data; const int reads = !list_empty(&dd->fifo_list[READ]); const int writes = !list_empty(&dd->fifo_list[WRITE]); struct request *rq; int data_dir; /* 兩個方向上的next_rq同時只能有一個為真 */ if (dd->next_rq[WRITE])rq = dd->next_rq[WRITE]; elserq = dd->next_rq[READ]; /* 如果有rq并且批量disaptch未到上限,則直接進行dispatch */ if (rq && dd->batching < dd->fifo_batch)/* we have a next request are still entitled to batch */goto dispatch_request; if (reads) {BUG_ON(RB_EMPTY_ROOT(&dd->sort_list[READ]));/* 觸發寫請求饑餓線 , 必須處理寫請求了 */if (writes && (dd->starved++ >= dd->writes_starved))goto dispatch_writes;data_dir = READ;goto dispatch_find_request; } if (writes) {dispatch_writes:BUG_ON(RB_EMPTY_ROOT(&dd->sort_list[WRITE]));dd->starved = 0;data_dir = WRITE;goto dispatch_find_request; } return 0;dispatch_find_request: /** 我們不是處理批量請求,而是選擇數據方向上最優的請求*/ /** 如果fifo_list有超時或者下一個請求的方向變了,就去* fifo_list去request,然后還得執行下面的dispatch_request*/ /** 該請求方向存在即將餓死的請求,或不存在批量處理的請求,* 則先從FIFO隊列頭取一個請求*/ if (deadline_check_fifo(dd, data_dir) || !dd->next_rq[data_dir]) {rq = rq_entry_fifo(dd->fifo_list[data_dir].next); } else {/** 為什么這里可以直接從fifo_list取而不是sort_list,因為* 最終都需要通過rq的rb_node到sort_list找*//* 按照扇區順序處理請求 */rq = dd->next_rq[data_dir]; } /* 啟動新一批請求dispatch */ dd->batching = 0;dispatch_request: /** rq is the selected appropriate request.*/ dd->batching++; /** 從fifo_list和sort_list中刪除,再加入req->queuelist中 , 這里就從* IO調度層離開了,移動一個請求到請求隊列的派發隊列*/ deadline_move_request(dd, rq); return 1;}

推薦閱讀