互联网公司不关注真实的文件系统,他们关注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是不是优先级应该更高一些?因为文件系统层面还在那等着呢!

IO调度的更多相关文章

  1. 编写简单的ramdisk(选择IO调度器)

    前言 目前linux中包含anticipatory.cfq.deadline和noop这4个I/O调度器.2.6.18之前的linux默认使用anticipatory,而之后的默认使用cfq.我们在前 ...

  2. IO调度器

    由于对blktrace的好奇,来到了block层.通过阅读block层的代码,自己的几个错误认知被纠正,比如 一) 同步操作时,进程是在驱动中睡觉真实情况是:进程在文件系统睡觉 二) 对同一个数据块的 ...

  3. Linux IO Scheduler(Linux IO 调度器)

    每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交的request.I/O调度器的基本目的是将请求按照它们对应在块设 ...

  4. linux IO调度

    I/O 调度算法再各个进程竞争磁盘I/O的时候担当了裁判的角色.他要求请求的次序和时机做最优化的处理,以求得尽可能最好的整体I/O性能.在linux下面列出4种调度算法CFQ (Completely ...

  5. Linux IO调度器相关算法介绍(转)

    IO调度器(IO Scheduler)是操作系统用来决定块设备上IO操作提交顺序的方法.存在的目的有两个,一是提高IO吞吐量,二是降低IO响应时间.然而IO吞吐量和IO响应时间往往是矛盾的,为了尽量平 ...

  6. Linux的IO调度

    Linux的IO调度 IO调度发生在Linux内核的IO调度层.这个层次是针对Linux的整体IO层次体系来说的.从read()或者write()系统调用的角度来说,Linux整体IO体系可以分为七层 ...

  7. IO队列和IO调度

    IO体系概览 先看看本文主题IO调度和IO队列处于整个IO体系的哪个位置,这个IO体系是非常重要的,了解IO体系我们可以对整个IO过程有个全面的认识.虽然一下两下并不清楚IO体系各个部分的细节,但是我 ...

  8. Linux IO 调度器

    Linux IO Scheduler(Linux IO 调度器) 每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交 ...

  9. IO调度器原理介绍

    IO调度器(IO Scheduler)是操作系统用来决定块设备上IO操作提交顺序的方法.存在的目的有两个,一是提高IO吞吐量,二是降低IO响应时间.然而IO吞吐量和IO响应时间往往是矛盾的,为了尽量平 ...

  10. Linux IO Scheduler(Linux IO 调度器)【转】

    每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交的request.I/O调度器的基本目的是将请求按照它们对应在块设 ...

随机推荐

  1. springboot中有用的几个有用aware以及bean操作和数据源操作

    本文参考了: https://blog.csdn.net/derrantcm/article/details/76652951 https://blog.csdn.net/derrantcm/arti ...

  2. python核心编程2 第十三章 练习

    13-3.对类进行定制.写一个类,用来将浮点型值转换为金额. class MoneyFmt(object): def __init__(self, value=0.0, flag='-'): self ...

  3. sudo及visudo

    sudo是一种权限管理机制,管理员可以授权普通用户去执行root的操作,而不需要知道root的密码,它依赖于/etc/sudoers这个文件,可以授权给哪个用户在哪个主机上能够以管理员的身份执行什么样 ...

  4. 齐博cms最新SQL注入网站漏洞 可远程执行代码提权

    齐博cms整站系统,是目前建站系统用的较多的一款CMS系统,开源,免费,第三方扩展化,界面可视化的操作,使用简单,便于新手使用和第二次开发,受到许多站长们的喜欢.开发架构使用的是php语言以及mysq ...

  5. 006---Python基本数据类型--集合

    集合 .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px ...

  6. R语言学习笔记(十六):构建分割点函数

    选取预测概率的分割点 cutoff<- function(n,p){ pp<-1 i<-0 while (pp>=0.02) { model.predfu<-rep(&q ...

  7. js倒计时页面跳转

    HTML: <p><span id="timer">60</span>s 后跳转到百度首页</p> JS: //倒计时方法 func ...

  8. Git的升级版本

    关于升级版本,例如我们要升级service版本,我们可以这样子操作 1.在master里面pull完了之后,到自己的分支,然后merge master里面的代码,然后把pom文件 里面的版本升一级,然 ...

  9. MyBatis的笔记

    1.#{}和${}的区别是什么? #{}是预编译处理,${}是字符串替换. #{}是sql的参数占位符,${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替 ...

  10. 问题:docker pull 用户登陆tricky,Error response from daemon: unauthorized: incorrect username or password

    问题描述: PS C:\WINDOWS\system32> docker pull rabbitmqUsing default tag: latest Please login prior to ...