免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1968 | 回复: 0
打印 上一主题 下一主题

make request中电梯算法应用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-03 12:16 |只看该作者 |倒序浏览
static int __make_request(request_queue_t *q, struct bio *bio)
{
struct request *req, *freereq = NULL;
int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err;
sector_t sector;
sector = bio->bi_sector;
nr_sectors = bio_sectors(bio);
cur_nr_sectors = bio_cur_sectors(bio);
rw = bio_data_dir(bio);
/*
  * low level driver can indicate that it wants pages above a
  * certain limit bounced to low memory (ie for highmem, or even
  * ISA dma in theory)
  */
blk_queue_bounce(q, &bio);
spin_lock_prefetch(q->queue_lock);
barrier = bio_barrier(bio);
if (barrier && !(q->queue_flags & (1
again:
spin_lock_irq(q->queue_lock);
if (elv_queue_empty(q)) {
  blk_plug_device(q);
  goto get_rq;
}
if (barrier)
  goto get_rq;
/* 首先判断这个bio是否可以加到已经存在的request 中,
* 这个函数会调用各个电梯算法的merge函数,这些merge
* 函数,一般都是先把这个bio向刚刚merge国的request中再次
* merge,如果不行,就查找hash函数寻找这个bio 可以merge进的
* request,对于deadline anticipatory算法,hash对应的request都在排序队列中,
* 一旦这个request移进dipatch 队列,就从hash表中删除了
*/
el_ret = elv_merge(q, &req, bio);
switch (el_ret) {
  case ELEVATOR_BACK_MERGE:
   BUG_ON(!rq_mergeable(req));
   if (!q->back_merge_fn(q, req, bio))
    break;
   req->biotail->bi_next = bio;
   req->biotail = bio;
   req->nr_sectors = req->hard_nr_sectors += nr_sectors;
   drive_stat_acct(req, nr_sectors, 0);
   if (!attempt_back_merge(q, req))
    elv_merged_request(q, req);
   goto out;
  case ELEVATOR_FRONT_MERGE:
   BUG_ON(!rq_mergeable(req));
   if (!q->front_merge_fn(q, req, bio))
    break;
   bio->bi_next = req->bio;
   req->cbio = req->bio = bio;
   req->nr_cbio_segments = bio_segments(bio);
   req->nr_cbio_sectors = bio_sectors(bio);
   /*
    * may not be valid. if the low level driver said
    * it didn't need a bounce buffer then it better
    * not touch req->buffer either...
    */
   req->buffer = bio_data(bio);
   req->current_nr_sectors = cur_nr_sectors;
   req->hard_cur_sectors = cur_nr_sectors;
   req->sector = req->hard_sector = sector;
   req->nr_sectors = req->hard_nr_sectors += nr_sectors;
   drive_stat_acct(req, nr_sectors, 0);
   if (!attempt_front_merge(q, req))
    elv_merged_request(q, req);
   goto out;
  /*
   * elevator says don't/can't merge. get new request
   */
  case ELEVATOR_NO_MERGE:
   break;
  default:
   printk("elevator returned crap (%d)\n", el_ret);
   BUG();
}
/*
  * Grab a free request from the freelist - if that is empty, check
  * if we are doing read ahead and abort instead of blocking for
  * a free slot.
  */
get_rq:
if (freereq) {
  req = freereq;
  freereq = NULL;
} else {
  spin_unlock_irq(q->queue_lock);
  if ((freereq = get_request(q, rw, GFP_ATOMIC)) == NULL) {
   /*
    * READA bit set
    */
   err = -EWOULDBLOCK;
   if (bio_rw_ahead(bio))
    goto end_io;

   freereq = get_request_wait(q, rw);
  }
  goto again;
}
req->flags |= REQ_CMD;
/*
  * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST)
  */
if (bio_rw_ahead(bio) || bio_failfast(bio))
  req->flags |= REQ_FAILFAST;
/*
  * REQ_BARRIER implies no merging, but lets make it explicit
  */
if (barrier)
  req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
req->errors = 0;
req->hard_sector = req->sector = sector;
req->hard_nr_sectors = req->nr_sectors = nr_sectors;
req->current_nr_sectors = req->hard_cur_sectors = cur_nr_sectors;
req->nr_phys_segments = bio_phys_segments(q, bio);
req->nr_hw_segments = bio_hw_segments(q, bio);
req->nr_cbio_segments = bio_segments(bio);
req->nr_cbio_sectors = bio_sectors(bio);
req->buffer = bio_data(bio); /* see ->buffer comment above */
req->waiting = NULL;
req->cbio = req->bio = req->biotail = bio;
req->rq_disk = bio->bi_bdev->bd_disk;
req->start_time = jiffies;
/* 底层调用各个电梯算法的add request函数,对deadline 和
* anticipatory而言,这些新请求会加到排序队列中
*
*/
add_request(q, req);
out:
if (freereq)
  __blk_put_request(q, freereq);
if (bio_sync(bio))
  __generic_unplug_device(q);
spin_unlock_irq(q->queue_lock);
return 0;
end_io:
bio_endio(bio, nr_sectors

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/84444/showart_1810913.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP