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;}

推荐阅读