Linux IO调度层分析-3

 

我们知道,每个块设备程序都有一个请求队列与之关联。在块设备初始化时,会分配并初始化请求队列。在这个时候,我们便可以为块设备驱动程序指定特定的IO调度算法,默认情况下是强制使用系统默认的调度算法。

熟悉块设备驱动的人知道,内核是通过generic_make_request函数来不断转发bio,直到该bio被挂载到物理设备的请求队列中。generic_make_request函数会获取bio所指向bdev的请求队列,并通过请求队列的q->make_request_fn方法来下发bio。如果该bdev指向的是物理设备时,make_request_fn是由内核的__make_request函数来实现,通常IO调度也就是在该函数中发生。该函数过程分析如下(只列出与IO调度有关系的部分)

int __make_request(request_queue_t *q, struct bio *bio)

{

       ……

el_ret = elv_merge(q, &req, bio);

switch (el_ret) {

//前两种可以合并

case ELEVATOR_BACK_MERGE:

       if (!ll_back_merge_fn(q, req, bio))

              break;

……

//插入到链表尾部

req->biotail->bi_next = bio;

req->biotail = bio;

……

if (!attempt_back_merge(q, req))

elv_merged_request(q, req, el_ret);

goto out;

case ELEVATOR_FRONT_MERGE:

……

//插入到链表头

bio->bi_next = req->bio;

req->bio = bio;

……

if (!attempt_front_merge(q, req))

elv_merged_request(q, req, el_ret);

goto out;

//不能合并,需要新创一个request

/* ELV_NO_MERGE: elevator says don't/can't merge. */

default:

;

}

       ……

}

elv_merge函数相当重要,它试图在请求队列中找到一个能够合并该biorequest,函数返回三个可能值:

ELEVATOR_NO_MERGE:队列已经存在的请求中不能包含bio结构,需要创建一个新请求。

ELEVATOR_BACK_MERGEbio结构可作为末尾的bio而插入到某个请求中;

ELEVATOR_FRONT_MERGEbio结构可作为某个请求的第一个bio被插入;

可将bio合并到request

elv_merge函数中,首先试图将bio合并到上一次被合并的req中。如果可以合并的话,返回结果。q->last_merge保存上一次合并的请求的指针。

       if (q->last_merge) {

              ret = elv_try_merge(q->last_merge, bio);

              if (ret != ELEVATOR_NO_MERGE) {

                     *req = q->last_merge;

                     return ret;

              }

       }

否则,通过elv_rqhash_find函数在调度算法的hash表(即elevator_queue中的hash字段)中查找可以将bio插入到某个req末尾的请求是否存在,如果存在,则返回ELEVATOR_BACK_MERGE,表明bio可作为末尾的bio而插入到某个请求中。

       __rq = elv_rqhash_find(q, bio->bi_sector);

       if (__rq && elv_rq_merge_ok(__rq, bio)) {

              *req = __rq;

              return ELEVATOR_BACK_MERGE;

       }

如果hash表中不存在这样的req

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值