1. 为什么要使用多队列

在主机中,多cpu运行多个线程,每个线程都能和文件系统交互,文件系统层也是用多线程和bio层交互,但是,块设备层只有一个队列:

在块设备层,来自多个cpu的bio请求被放在同一个队列中,造成阻塞:

因此,提出了多队列的方法,在块设备层也做成多线程:

但是,在块设备层实现多个队列并不能像文件系统一样考虑,因为块设备层需要与硬件交互,这需要硬件也支持多队列,最理想的情况是,硬件支持的队列足够多,上层的每个队列(基于软件的队列),都有硬件队列和其关联。但有些时候,硬件支持的队列有限,就形成如上图的关联关系:上图中有3个硬件队列,但是,上层总共形成了6个队列(cpu到文件系统到bio层,都是6个基于软件的队列),因此,到达块设备层时,块设备会将2个基于软件的队列和1个硬件队列关联起来。

以下是细节图:

2. 更多信息

在编程中,一般用到的变量名和blk_mq 中各部分的对应关系:

图源:https://img-blog.csdnimg.cn/20191110221335681.png

图源:https://img-blog.csdnimg.cn/20191110221243484.png

图源:https://img-blog.csdnimg.cn/2019111022505564.png

blk_mq 中的 io 流:

块设备层的io流:

因为来自上层的多个队列在块设备层被放在不同的队列中,一个需要解决的问题是:当块设备的层提交给下层设备的bio请求完成后,如何从返回的请求(complete IO)中区分其来自块设备中的哪一个队列。一种方法是使用IPI(处理器间中断处理),示意图如下:

IPI(inter-processorinterrupt)是一种特别的中断。在对称多处理器 (SMP)环境下,它可以被任意一个处理器用来对另一个处理器产生中断。IPIs典型地被用来实现高速缓存间的一致性同步(Cache Coherency Synchronization)

https://blog.csdn.net/xkjcf/article/details/7772849

另一个方法是使用一串数字来标记请求来自哪个队列,即:硬件从请求中获得 tag,请求完成后,在返回给 completion IO 池的的请求中也带上该 tag,示意图如下:

3. 使用blk_mq的效果

测试 IOPS 的结果:

可以看到,随着线程的增加,使用 blk_mq 的效果明显比没使用blk_mq的单队列好。

即使在只有一个硬件队列的情况下,增加块设备层的队列也会提升性能:

因为,当块设备层只有一个队列的时候,大部分时间都花在获取设备锁上面。

相关资料:

Linux NVMe Driver学习笔记大合集: 从NVMe驱动代码进行理解,有 blk_mq 的部分;

Multi-Queu on block layer in Linux Kernel: 从代码理解 linux 内核中的 blk_mq 的实现。

参考资料:http://events.static.linuxfound.org/sites/events/files/slides/vault-2016.pdf

blk_mq多队列块设备浅析的更多相关文章

  1. linux驱动开发之块设备学习笔记

    我的博客主要用来存放我的学习笔记,如有侵权,请与我练习,我会立刻删除.学习参考:http://www.cnblogs.com/yuanfang/archive/2010/12/24/1916231.h ...

  2. 乾坤合一~Linux设备驱动之块设备驱动

    1. 题外话 在蜕变成蝶的一系列学习当中,我们已经掌握了大部分Linux驱动的知识,在乾坤合一的分享当中,以综合实例为主要讲解,在一个月的蜕茧成蝶的学习探索当中,觉得数据结构,指针,链表等等占据了代码 ...

  3. [原] KVM 虚拟化原理探究(6)— 块设备IO虚拟化

    KVM 虚拟化原理探究(6)- 块设备IO虚拟化 标签(空格分隔): KVM [toc] 块设备IO虚拟化简介 上一篇文章讲到了网络IO虚拟化,作为另外一个重要的虚拟化资源,块设备IO的虚拟化也是同样 ...

  4. 嵌入式Linux驱动学习之路(二十一)字符设备驱动程序总结和块设备驱动程序的引入

    字符设备驱动程序 应用程序是调用C库中的open read write等函数.而为了操作硬件,所以引入了驱动模块. 构建一个简单的驱动,有一下步骤. 1. 创建file_operations 2. 申 ...

  5. linux块设备驱动之实例

    1.注册:向内核注册个块设备驱动,其实就是用主设备号告诉内核这个代表块设备驱动 sbull_major  =  register_blkdev(sbull_major, "sbull&quo ...

  6. Smart210学习记录------块设备

    转自:http://bbs.chinaunix.net/thread-2017377-1-1.html 本章的目的用尽可能最简单的方法写出一个能用的块设备驱动.所谓的能用,是指我们可以对这个驱动生成的 ...

  7. linux下的块设备驱动(一)

    块设备的驱动比字符设备的难,这是因为块设备的驱动和内核的联系进一步增大,但是同时块设备的访问的几个基本结构和字符还是有相似之处的. 有一句话必须记住:对于存储设备(硬盘~~带有机械的操作)而言,调整读 ...

  8. Linux 块设备驱动 (二)

    linux下Ramdisk驱动 1 什么是Ramdisk Ramdisk是一种模拟磁盘,其数据实际上是存储在RAM中,它使用一部分内存空间来模拟出一个磁盘设备,并以块设备的方式来组织和访问这片内存.对 ...

  9. Linux 块设备驱动 (一)

    1.块设备的I/O操作特点 字符设备与块设备的区别: 块设备只能以块为单位接受输入和返回输出,而字符设备则以字符为单位. 块设备对于I/O请求有对应的缓冲区,因此它们可以选择以什么顺序进行响应,字符设 ...

  10. linux下的块设备驱动(二)

    上一章主要讲了请求队列的一系列问题.下面主要说一下请求函数.首先来说一下硬盘类块设备的请求函数. 请求函数可以在没有完成请求队列的中的所有请求的情况下就返回,也可以在一个请求都不完成的情况下就返回. ...

随机推荐

  1. Idea无法下载插件或下载插件报错

    Plugin Python was not installed: Cannot download 'https://plugins.jetbrains. file ->  settings -& ...

  2. Yarn公平调度器(Fair Scheduler)切换容量调度器(Capacity Scheduler)

    一.调度器简介 Fair Scheduler称为公平调度器,是Apache YARN内置的调度器.公平调度器主要目标是实现YARN上运行的应用能公平的分配到资源,其中各个队列使用的资源根据设置的权重( ...

  3. ClickHouse 常用语句

    一.常用操作 1.建数据库 连接数据库:clickhouse-client -h 10.0.0.0 --port 9000 -u test_user --password test_password  ...

  4. 多线程之lamda表达式

    代码简化过程  public class TestLambda1 { ​     //3.静态内部类     static class Like2 implements ILike{          ...

  5. pytest自动化测试 - 我对测试用例超时处理的一点看法

    1 pytest自动化测试 - 我对测试用例超时处理的一点看法 1.1 背景   用例在执行过程中,可能由于网络等待,或者等待一些特殊的文件,而又由于一些异常,导致这些条件一直不能满足,用例卡死,这种 ...

  6. mangoDB操作指令

    studio 3T 更新或插入字段: db.getCollection("data_379129").update({},{$set: {'connectedStatus':Num ...

  7. autMan奥特曼机器人-Linux、Windows、docker安装教程

    autMan简介 autMan是机器人牵引的扩展性极强的一站式解决方案 原生支持对接qq框架.qq频道.微信框架(酷V西瓜可爱猫千寻鲲鹏). 内置微信.微信客服.公众号.钉钉.飞书.tg客户端.tg机 ...

  8. 在 Mac 上解决 LM Studio 无法下载模型的问题(国内镜像替换教程)

    如果你在使用 LM Studio 时遇到类似 There was an error fetching results from Hugging Face 或 Model details error: ...

  9. 内网环境部署Deepseek+Dify,构建企业私有化AI应用

    0.简介 公司为生产安全和保密,内部的服务器不可连接外部网络,为了可以在内网环境下部署,采用的方案为ollama(Docker)+Dify(Docker Compose),方便内网环境下迁移和备份,下 ...

  10. 【Bug记录】[@vue/compiler-sfc] `defineProps` is a compiler macro and no longer needs to be imported.

    [Bug记录][@vue/compiler-sfc] defineProps is a compiler macro and no longer needs to be imported. Vue3项 ...