zoukankan      html  css  js  c++  java
  • IO调度

    互联网公司不关注真实的文件系统,他们关注VFS层,关注block层,关注IO的管控。

    queue->make_request_fn ( blk_queue_bio ),其中blk_queue_bio是把bio插入到request queue中的核心函数

    request_queue 和 request

    blk_queue_bio 函数是进行IO的调度合并

    主要做了三件事情:

    1)进行请求的后向合并;2)进行请求的前向合并;3)如果无法合并请求,那么为bio创建一个request,然后进行调度。

    在bio合并过程中,最为关键的函数是elv_merge。该函数主要工作是判断bio是否可以后向合并或者前向合并。对于所有的调度器,后向合并的逻辑都是相同的。在系统中维护了request hash表

    当IO利用generic_make_request来到块设备层之后,对其进行处理的重要函数blk_queue_bio的主要任务是合并IO。由于不同的调度器有不同的合并方法,IO分类方法,所以,具有调度器的算法采用钩子方式实现。

    IO 调度器能干的事情非常简单,但是

    1)疑问:requeue_queue中总共有几个队列?同步写、同步读、预读(异步读)、异步写这四种?

    2)存储和计算:存储器的处理能力是有限的,那么尤其是进入了BLOCK层之后,到底有没有那么多的BIO下发下来?!

    request_list 结构体

      55 struct request_list {
      56     struct request_queue    *q; /* the queue this rl belongs to */
      57 #ifdef CONFIG_BLK_CGROUP
      58     struct blkcg_gq     *blkg;  /* blkg this request pool belongs to */
      59 #endif
      60     /*
      61      * count[], starved[], and wait[] are indexed by
      62      * BLK_RW_SYNC/BLK_RW_ASYNC
      63      */
      64     int         count[2]; 记录着同步的IO和异步的IO BLK_RW_SYNC/BLK_RW_ASYNC
      65     int         starved[2];   
      66     mempool_t       *rq_pool;
      67     wait_queue_head_t   wait[2];
      68     unsigned int        flags;
      69 };
    

    __get_request 函数中会有对是否是SYNC的判断

    bio 和 request 都是有都是是否可以merge的判断

    elv_rqhash_find 在request_queue 中找

    blk_rq_merge_ok 判断IO是否能够合并。好像是没有对SYNC做判断呢!

    在block层的同步IO和异步的IO是如何管理的呢?

    目前的结论是,IO调度器只会管理着读和写,但是并不会管理sync/async这个操作

    bdi_writeback_congested

    在函数blk_rq_merge_ok中,有两个判断条件是否是冲突的:

    if (req_op(rq) != bio_op(bio)) return false;

    if (bio_data_dir(bio) != rq_data_dir(rq)) return false;

    这两个地方不都是判断读和写的吗?

    bio_data_dir:

    enum req_op {

      REQ_OP_READ,

      REQ_OP_WRITE,

      REQ_OP_DISCARD,

      REQ_OP_SECURE_ERASE,

      REQ_OP_WRITE_SAME,

      REQ_OP_FLUSH

    }

    request_list 中 有一个最重要的结构,里面记录着设备上有多少个同步IO、异步IO、分配一个request时也是从这个地方分配

    一个后备存储的IO都放在哪里了?

    blk_queue_bio --> add_acct_request --> __elv_add_request

    request下发到block层之后,会在电梯的各种链表、树中管理,但是这个表中还是没有区分同步和异步。

    比如我一个SYNC的BIO下来了,那么也是简单地放到链里吗?这种IO是不是优先级应该更高一些?因为文件系统层面还在那等着呢!

  • 相关阅读:
    hdu 2553 N皇后问题(dfs)
    hdu 1043 Eight(双向bfs)
    牛人的ACM经验 (转)
    康托和逆康托展开(转)
    hiho Mission Impossible 6(模拟 未提交验证。。)
    数组越界也可以这么巧~~~
    poj 1679 The Unique MST(次小生成树)
    zoj 3204 Connect them(最小生成树)
    hdu 4463 Outlets(最小生成树)
    廖雪峰Java1-2程序基础-8字符和字符串
  • 原文地址:https://www.cnblogs.com/honpey/p/6716117.html
Copyright © 2011-2022 走看看