btt User Guide在百度找了3天没找到,bing也不行,结果google第一页第5个结果就是。

可恶的GFW

http://www.fis.unipr.it/doc/blktrace-1.0.1/blktrace.pdf

通过blktrace btt工具分析得知,block在get request时的event有如下:

  • A:表示IO被重新映射到不同的设备(IO was remapped to a different device)。
  • B: IO反弹(io bounced)
  • C: IO完成。(io completion)
  • D: IO发送给驱动(io issued to driver)
  • F: 在队列中请求合并前的IO(io front merged with request on queue)
  • G: 获取请求(get request)
  • I: IO插入到请求队列(io inserted onto request queue)
  • M: 在队列中请求合并后的IO(io back merged with request on queue)
  • P: 阻塞请求(Plug request)
  • Q: IO已被请求队列处理(io handled by request queue code)
  • S: 请求睡眠(sleep request)
  • T: 拔下由于超时(unplug due to timeout)
  • U: 分发请求(unplug request)
  • X: 分拆IO(split)

根据Understanding the Linux Kernel, 3rd Edition的描述,可以确定以上的动作顺序。

Q------------>G------------>I------------>D------------>C

(SA)X?                             F&M,T&U

14.2.3. Submitting a Request

Once the bio descriptor has been properly initialized, the kernel invokes the generic_make_request( ) function, which is the main entry point of the generic block layer. The function essentially executes the following steps:

  1. Checks that bio->bi_sector does not exceed the number of sectors of the block device. If it does, the function sets the BIO_EOF flag of bio->bi_flags, prints a kernel error message, invokes the bio_endio() function, and terminates. bio_endio( ) updates the bi_size and bi_sector fields of the bio descriptor, and it invokes the bi_end_io bio's method. The implementation of the latter function essentially depends on the kernel component that has triggered the I/O data transfer; we will see some examples of bi_end_io methods in the following chapters.

  2. Gets the request queue q associated with the block device (see the section "Request Queue Descriptors" later in this chapter); its address can be found in the bd_disk field of the block device descriptor, which in turn is pointed to by the bio->bi_bdev field.

  3. Invokes block_wait_queue_running( ) to check whether the I/O scheduler currently in use is being dynamically replaced; in this case, the function puts the process to sleep until the new I/O scheduler is started (see the next section "The I/O Scheduler").

  4. Invokes blk_partition_remap( ) to check whether the block device refers to a disk partition (bio->bi_bdev not equal to bio->bi_dev->bd_contains; see the section "Block Devices" later in this chapter). In this case, the function gets the hd_struct descriptor of the partition from the bio->bi_bdev field to perform the following substeps:

    1. Updates the read_sectors and reads fields, or the write_sectors and writes fields, of the hd_struct descriptor, according to the direction of data transfer.

    2. Adjusts the bio->bi_sector field so as to transform the sector number relative to the start of the partition to a sector number relative to the whole disk.

    3. Sets the bio->bi_bdev field to the block device descriptor of the whole disk (bio->bd_contains).

    From now on, the generic block layer, the I/O scheduler, and the device driver forget about disk partitioning, and work directly with the whole disk.

  5. Invokes the q->make_request_fn method to insert the bio request in the request queue q.

  6. Returns.

14.3.5. Issuing a Request to the I/O Scheduler

As seen in the section "Submitting a Request" earlier in this chapter, the generic_make_request( ) function invokes the make_request_fn method of the request queue descriptor to transmit a request to the I/O scheduler. This method is usually implemented by the _ _make_request( ) function; it receives as its parameters a request_queue descriptor q and a bio descriptor bio, and it performs the following operations:

  1. Invokes the blk_queue_bounce( ) function to set up a bounce buffer, if required (see later). If a bounce buffer was created, the _ _make_request( ) function operates on it rather than on the original bio.

  2. Invokes the I/O scheduler function elv_queue_empty( ) to check whether there are pending requests in the request queuenotice that the dispatch queue might be empty, but other queues of the I/O scheduler might contain pending requests. If there are no pending requests, it invokes the blk_plug_device( ) function to plug the request queue (see the section "Activating the Block Device Driver" earlier in this chapter), and jumps to step 5.

  3. Here the request queue includes pending requests. Invokes the elv_merge( ) I/O scheduler function to check whether the new bio can be merged inside an existing request. The function may return three possible values:

    • ELEVATOR_NO_MERGE: the bio cannot be included in an already existing request: in that case, the function jumps to step 5.

    • ELEVATOR_BACK_MERGE: the bio might be added as the last bio of some request req: in that case, the function invokes the q->back_merge_fn method to check whether the request can be extended. If not, the function jumps to step 5. Otherwise it inserts the bio descriptor at the tail of the req's list and updates the req's fields. Then, it tries to merge the request with a following request (the new bio might fill a hole between the two requests).

    • ELEVATOR_FRONT_MERGE: the bio can be added as the first bio of some request req: in that case, the function invokes the q->front_merge_fn method to check whether the request can be extended. If not, it jumps to step 5. Otherwise, it inserts the bio descriptor at the head of the req's list and updates the req's fields. Then, the function tries to merge the request with the preceding request.

  4. The bio has been merged inside an already existing request. Jumps to step 7 to terminate the function.

  5. Here the bio must be inserted in a new request. Allocates a new request descriptor. If there is no free memory, the function suspends the current process, unless the BIO_RW_AHEAD flag in bio->bi_rw is set, which means that the I/O operation is a read-ahead (see Chapter 16); in this case, the function invokes bio_endio( ) and terminates: the data transfer will not be executed. For a description of bio_endio( ), see step 1 of generic_make_request( ) in the earlier section "Submitting a Request."

  6. Initializes the fields of the request descriptor. In particular:

    1. Initializes the various fields that store the sector numbers, the current bio, and the current segment according to the contents of the bio descriptor.

    2. Sets the REQ_CMD flag in the flags field (this is a normal read or write operation).

    3. If the page frame of the first bio segment is in low memory, it sets the buffer field to the linear address of that buffer.

    4. Sets the rq_disk field with the bio->bi_bdev->bd_disk address.

    5. Inserts the bio in the request list.

    6. Sets the start_time field to the value of jiffies.

  7. All done. Before terminating, however, it checks whether the BIO_RW_SYNC flag in bio->bi_rw is set. If so, it invokes generic_unplug_device( ) on the request queue to unplug the driver (see the section "Activating the Block Device Driver" earlier in this chapter).

  8. Terminates.

未完待续

IO在block级别的过程分析的更多相关文章

  1. Block层也是有IO的优先级的

    ---恢复内容开始--- 今天查看iotop的原理,竟然发现了IO优先级一说,IO是block层cfs调度器中的概念 block层也有一个类似于CPU的调度算法 对进程分成三个级别:RT,BE,IDL ...

  2. 限制容器的 Block IO - 每天5分钟玩转 Docker 容器技术(29)

    前面学习了如何限制容器对内存和CPU的使用,本节我们来看 Block IO. Block IO 是另一种可以限制容器使用的资源.Block IO 指的是磁盘的读写,docker 可通过设置权重.限制 ...

  3. 网络编程进阶:并发编程之协程、IO模型

    协程: 基于单线程实现并发,即只用一个主线程(此时可利用的CPU只有一个)情况下实现并发: 并发的本质:切换+保存状态 CPU正在运行一个任务,会在两种情况下切走去执行其他任务(切换有操作系统强制控制 ...

  4. 36、IO模型与socketserver实现并发

    特别声明本随笔copy于egon(林海峰). 一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronou ...

  5. Python之IO模型

    IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞 ...

  6. 同步IO,异步IO,阻塞IO,非阻塞IO

    同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回.按照这个定义, 其实 ...

  7. Python并发编程之IO模型

    目录 IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) IO多路复用 异步IO IO模型比较分析 selectors模块 一.IO模型介绍 Stevens ...

  8. 转载博文: Py西游攻关之IO model

    Py西游攻关之IO model 转载:https://www.cnblogs.com/yuanchenqi/articles/5722574.html 事件驱动模型 上节的问题: 协程:遇到IO操作就 ...

  9. day 7-9 IO模型

    一,同步和异步,阻塞和非阻塞 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就 ...

随机推荐

  1. githubpage+hexo构建自己的个人博客

    就这有这么一天,我感觉博客园的博客页面实在太low了.完全跟不上现在潮流. https://segmentfault.com/a/1190000004947261 http://coolcao.com ...

  2. 这些HTML、CSS知识点,面试和平时开发都需要 No1-No4(知识点:HTML、CSS、盒子模型、内容布局)

    这些HTML.CSS知识点,面试和平时开发都需要 No1-No4   系列知识点汇总 这些HTML.CSS知识点,面试和平时开发都需要 No1-No4(知识点:HTML.CSS.盒子模型.内容布局) ...

  3. Python 中的那些坑总结——持续更新

    1.三元表达式之坑 很显然,Python把第一行的(10 + 4)看成了三元表达式的前部分,这个坑是看了<Python cookbook>(P5)中学到的,书中的代码: 2.Python生 ...

  4. OOP、AOP 、IoC和DI、ORM 概念

    OOP 面向对象编程(Object Oriented Programming) OOP引入封装.继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合. AOP 面向切面编程Aspect ...

  5. uva11551矩阵快速幂

    题目看了半天没看懂,,就是把一个数列更新r次,每次更新就是计算和,就是每一个数,只要出现了的表号都要加上去,具体看代码 矩阵快速幂实现加速 #include<map> #include&l ...

  6. MyBatis Generator去掉生成的注解

    是不是很讨厌mybatis Generator帮我们生成代码的时候在Mapper和mapper.xml文件中生成的一大堆注解?今天在看MyBatis Generator代码的时候发现,原来mybati ...

  7. halcon之屌炸天的自标定(1)

      本次先对halcon的自标定做个整体介绍,了解屌炸天的自标定在实际应用中的应用与实现方法,具体的编程细节将在后续的文章中介绍. halcon提供了一种自标定的算子,它可以在不用标定板的情况下,标定 ...

  8. 转载-LVS的三种工作模式

    来源地址:http://www.uml.org.cn/zjjs/201211124.asp 1.lvs简介         lvs是一个开源的软件,由毕业于国防科技大学的章文嵩博士于1998年5月创立 ...

  9. Artix-7 50T FPGA试用笔记之Create a simple MicroBlaze System

    前言:之前笔者的试用博文提到安富利这块板子非常适合MicroBlaze开发,同时网上关于MicroBlaze的资料非常少(或含糊不清),没有一篇能完整介绍VIVADO SDK的设计流程,所以笔者带来这 ...

  10. Junit4与junt3并存时产生的问题

    目前的项目里用junit写单元测试,使用的是junit4,由于大部分开发之前使用的都是junit3,对junit4还不是很熟悉,所以出现了junit3和4混合使用的情况,导致发生了一些问题,这里列举一 ...