IO调度 | Linux块设备中的IO路径及调度策略
当文件系统通过submit_bio提交IO之后,请求就进入了通用块层。通用块层会对IO进行一些预处理的动作,其目的是为了保证请求能够更加合理的发送到底层的磁盘设备,尽量保证性能最佳。这里面比较重要的就是IO调度模块。大家可能都听说过CFQ,除此之前还有DeadLine和Noop等,这些都是磁盘的调度算法。其中CFQ调度算法用的最多。
如果忽略块设备的层叠结构和各种映射,简化的结构大概有3层,如图1所示。这里的3层并非都是软件,还包含硬件。通用块层就不用多说了,这里主要完成IO的合并和调度等操作。其下是驱动层,驱动层是硬件的驱动程序,用于将IO请求转换为对硬件寄存器的操作(注:不同的块设备又有差异,必然iSCSI设备是不会有寄存器操作的)。物理设备不同该驱动层的程序就不同,比如对于SAS直连的磁盘,该驱动层的程序就是SAS驱动,而如果是FC-HBA卡连接的FC-SAN,那么这个驱动层就是FC驱动(比如Qlogic的驱动)。
图1 块设备分层
最下面一层是设备层,设备层通常是一个硬件设备。这里的硬件种类繁多,比如SAS卡、SATA卡、FC-HBA卡或者iSCSI-HBA卡等等。但有的时候又可能并不是硬件设备,比如对于iSCSI来说,该层可能是通过软件模拟的一个设备层,而其请求则是通过网卡发送到目标器端。
主要数据结构及流程
绝大多数程序都是由数据结构和算法2部分内容组成的,数据结构相当于程序的骨架,而算法则是程序的筋和肉。通过算法将数据结构关联起来,从而形成一个完整的整体。人类认识问题的规律是从具体到抽象,从简单到复杂,因此我们先从数据结构开始。理解了数据关键的数据结构,那我们就能更加容易的理解块设备IO的整个逻辑。
在块设备IO中最为关键的数据结构是request_queue,也就是请求队列。该数据结构的简图如图2所示,这个数据结构本身非常复杂,我们这里进行了简化,只保留了部分关键的成员。如图彩色部分是2个函数指针,分别用于接收请求和处理请求。
图2 请求队列数据结构
为了便于理解,我们这里举一个例子。以NBD块设备为例,在块设备初始化的时候make_request_fn被初始化为blk_queue_bio,request_fn被初始化为do_nbd_request。对于SCSI块设备而言,request_fn会被初始化为scsi_request_fn。
有了上面数据结构的知识及关键成员初始化的结果,接下来我们就可以分析一下块设备的整个流程的细节。块设备请求的入口是submit_bio,经过简单的检查后调用
由上述代码可以看出IO处理的入口函数其实是函数指针make_request_fn,而我们知道该指针实际上是函数blk_queue_bio。因此块设备的请求会由blk_queue_bio函数进行处理。
磁盘调度策略
Linux内核在设计磁盘的调度策略时提供了极大的灵活性。磁盘的调度策略以插件的注册到内核当中,也就是用户可以自由的选择磁盘的调度策略。
调度算法的思想其实非常简单,主要是通过对IO的排序、合并和批量处理来优化磁盘寻道和请求的处理时间。这里值得说明的目前的调度算法其实更多的是针对机械磁盘,因为机械磁盘磁头定位耗时占整个IO处理时间的很大比例。当然对于SSD磁盘,调度算法也有一定的帮助,这就需要针对IO的特性具体来看了。
图3 调度策略结构体
磁盘调度策略的结构体定义如图3所示,各个变量的含义也是比较明确,本文不再赘述。本文主要看一下 其中elevator_ops类型的变量ops,这个变量是调度策略具体的功能实现,任何调度算法都要实现其中某些函数。
调度策略的实现就是通过这些回调函数完成的。为了理解调度策略的函数集具体做哪些事情,本文整理了一个表格,我们先从整体上看一下每个函数具体做了哪些事情。对于调度策略来说,这里的函数并非每个都要实现,下表中只有带*的才是必须要实现的函数。
简而言之,上述回调函数的功能就是判断请求是否可以被合并、执行合并和请求下发等等操作。上述回调函数比较多,而且使用场景也比较复杂,具体使用分散在调度器的很多流程中。因此,我们很难一下子介绍清楚所有的场景。为了更加直观的理解上述回调函数的作用,我们以Deadline调度策略为例进行简单的介绍。
如图4是Deadline初始化的回调函数,从图中可以看出这里并没有初始化所有的回调函数,而只初始化了16个回调函数中的9个。
图4 Deadline回调函数
我们具体分析一下函数的调用场景,前文我们介绍到elevator_merge_fn函数用于查询可以与bio合并的请求。如图5所示为整个调用栈,入口为blk_queue_bio,这个函数我们之前介绍过,它就是调度程序的入口。该函数调用elv_merge用于查找是否有可以合并的请求,并返回。而elv_merge函数调用的正式Deadline调度器提供的回调函数。完成判断后,该函数会根据实际情况返回请求(或者没有找到,不返回)和可合并的方向(例如向前合并,向后合并等),后续流程就是进行具体的合并操作了。
图5 函数调用栈
由于IO调度涉及的流程比较多,限于本文篇幅,今天就先介绍到这里。后续我们再更加深入的介绍关于IO调度的其它内容。
IO调度 | Linux块设备中的IO路径及调度策略的更多相关文章
- linux块设备的IO调度算法和回写机制
************************************************************************************** 參考: <Linux ...
- Linux 块设备驱动 (一)
1.块设备的I/O操作特点 字符设备与块设备的区别: 块设备只能以块为单位接受输入和返回输出,而字符设备则以字符为单位. 块设备对于I/O请求有对应的缓冲区,因此它们可以选择以什么顺序进行响应,字符设 ...
- Linux块设备驱动详解
<机械硬盘> a:磁盘结构 -----传统的机械硬盘一般为3.5英寸硬盘,并由多个圆形蝶片组成,每个蝶片拥有独立的机械臂和磁头,每个堞片的圆形平面被划分了不同的同心圆,每一个同心圆称为一个 ...
- linux块设备驱动---相关结构体(转)
上回最后面介绍了相关数据结构,下面再详细介绍 块设备对象结构 block_device 内核用结构block_device实例代表一个块设备对象,如:整个硬盘或特定分区.如果该结构代表一个分区,则其成 ...
- linux 块设备-整理(一)
1. 基本概念: linux设备驱动开发详解(宋宝华): 字符设备与块设备 I/O 操作的不同如下. (1)块设备只能以块为单位接受输入和返回输出,而字符设备则以字节为单位. 大多数设备是字符设备,因 ...
- linux块设备驱动之实例
1.注册:向内核注册个块设备驱动,其实就是用主设备号告诉内核这个代表块设备驱动 sbull_major = register_blkdev(sbull_major, "sbull&quo ...
- 简单linux块设备驱动程序
本文代码参考<LINUX设备驱动程序>第十六章 块设备驱动程序 本文中的“块设备”是一段大小为PAGE_SIZE的内存空间(两个扇区,每个扇区512字节) 功能:向块设备中输入内容,从块设 ...
- (linux)块设备驱动程序
1.4.1 Linux块设备驱动程序原理(1) 顾名思义,块设备驱动程序就是支持以块的方式进行读写的设备.块设备和字符设备最大的区别在于读写数据的基本单元不同.块设备读写数据的基本单元为块,例如 ...
- linux块设备模型架构框架
Linux块设备的原理远比字符设备要复杂得多,尽管在linux这一块的方法论有很多相似之处,但考虑到它是用中块结构,它常常要搭配内存页管理,页缓冲块缓冲来改善硬盘访问的速度,按照块硬件最大的性能要求进 ...
随机推荐
- MSPBSL_Scripter编译
The BSL Scripter is a PC application that is available for Windows, Linux and Mac OS X. It is a user ...
- Masonry个人笔记
1.有些场合需要获取View在约束之后的frame.直接init初始化后取出来的均为(0,0,0,0).在以下方法中获取即可: View: - (void)layoutSubviews ViewCon ...
- 周伯通的空明拳,米诺斯的星尘傀儡线,SAP Kyma的Serverless
Jerry一直认为,金庸的<天龙八部>里的武学建模已经有点脱离传统武侠小说的范畴了,像已经走上玄幻道路的灵鹫宫"八荒六合唯我独尊功",以及杀伤力足够能被视为现代激光武器 ...
- 一组简单好看的css3渐变按钮
主要代码如下: body { background:#fff } /* Mixins */ /* bg shortcodes */ .bg-gradient1 span,.bg-gradient1:b ...
- 当跨域时,js ajax 请求出现options请求
上面有文章说过http的options. 查了很久.试了很多版本的jQuery,下面这段代码在同事的机子上测试是没有问题的.正常 的请求, 一在我机子上面就会出现option,网上说先向服务器预检等. ...
- Flutter中的替换路由、返回到根路由
替换路由 当我们有三个页面,页面1,页面2,页面3. 期望点击页面1按钮,跳转到页面2,页面2点击返回,跳转到页面1: 点击页面2按钮,跳转到页面3,页面3点击返回,跳转到页面1,而不是页面2. 这时 ...
- 【HICP Gauss】数据库 数据库管理(存储过程 函数 对象 近义词 触发器 事务类型)-9
存储过程存储过程在大新数据库系统中,一组为了完成特定功能的SQL语句集 存储在SQL数据库中 优势: SQL进行封装 调用方便 存储过程会进行编译 提升用户执行SQL语句集的速 ...
- Python更改pip源
Python更改pip源 pip源有以下 新版ubuntu要求使用https源,要注意.清华:https://pypi.tuna.tsinghua.edu.cn/simple阿里云:http://mi ...
- 算法笔记--BSGS && exBSGS 模板
https://www.cnblogs.com/sdzwyq/p/9900650.html 模板: unordered_map<int, int> mp; LL q_pow(LL n, L ...
- tensorflow几个常见错误
错误一:二分类,标签y ValueError: Cannot feed value of shape (128,1) for Tensor u'input_y_2:0', which has shap ...