歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux I/O Scheduler--CFQ(下)

前文介紹了CFQ調度器的一些概念和結構之間的關系,這裡再結合實際的代碼,來分析CFQ的工作流程。

Linux I/O Scheduler--CFQ(上) http://www.linuxidc.com/Linux/2012-12/76163.htm

CFQ調度器的定義如下:

static struct elevator_type iosched_cfq = {
 .ops = {
  .elevator_merge_fn =   cfq_merge,
  .elevator_merged_fn =  cfq_merged_request,
  .elevator_merge_req_fn = cfq_merged_requests,
  .elevator_allow_merge_fn = cfq_allow_merge,
  .elevator_dispatch_fn =  cfq_dispatch_requests,
  .elevator_add_req_fn =  cfq_insert_request,
  .elevator_activate_req_fn = cfq_activate_request,
  .elevator_deactivate_req_fn = cfq_deactivate_request,
  .elevator_queue_empty_fn = cfq_queue_empty,
  .elevator_completed_req_fn = cfq_completed_request,
  .elevator_former_req_fn = elv_rb_former_request,
  .elevator_latter_req_fn = elv_rb_latter_request,
  .elevator_set_req_fn =  cfq_set_request,
  .elevator_put_req_fn =  cfq_put_request,
  .elevator_may_queue_fn = cfq_may_queue,
  .elevator_init_fn =  cfq_init_queue,
  .elevator_exit_fn =  cfq_exit_queue,
  .trim =    cfq_free_io_context,
 },
 .elevator_attrs = cfq_attrs,
 .elevator_name = "cfq",
 .elevator_owner = THIS_MODULE,
};

可以看到CFQ調度器涉及到的操作函數還是比較多的,這裡我只打算選一些和提交bio以及request相關的函數進行分析。在提交bio的時候,如果在通用層尋找可以合並bio的途徑失敗,要通過cfq_merge()來判斷是否能夠將bio插入到某個request的bio鏈表首部

static struct request *
cfq_find_rq_fmerge(struct cfq_data *cfqd, struct bio *bio)
{
 struct task_struct *tsk = current;
 struct cfq_io_context *cic;
 struct cfq_queue *cfqq;

 //在進程的io_context中,找到進程特定於塊設備的cfq_io_context
 cic = cfq_cic_lookup(cfqd, tsk->io_context);
 if (!cic)
  return NULL;

 //根據同步還是異步,確定cfq_queue
 cfqq = cic_to_cfqq(cic, cfq_bio_sync(bio));
 if (cfqq) {
  sector_t sector = bio->bi_sector + bio_sectors(bio);//得到末尾扇區號

  //從cfq_queue的紅黑樹中查找對應的節點
  return elv_rb_find(&cfqq->sort_list, sector);
 }

 return NULL;
}

Copyright © Linux教程網 All Rights Reserved