无线电爱好网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

无线电爱好网 首页 技术应用 单片机 查看内容

Multi-queue 架构分析

2022-10-13 10:16| 发布者: 闪电| 查看: 8| 评论: 0

摘要: Linux上传统的块设备层(Block Layer)和IO调度器(如cfq)主要是针对HDD(hard disk drivers)设计的。我们知道,HDD设备的随机IO性能很差,吞吐量大约是几百IOPS(IOs per second),延迟在毫秒级,所以当时IO性能 ...


  • UFS设备完成一个IO请求之后,触发中断, ufshc(UFS host controller)驱动负责处理这个中断(服务例程是ufshc_intr),通过中断状态寄存器(REG_INTERRUPT_STATUS)判断是否有IO请求完成(UTP_TRANSFER_REQ_COMPL位),通过对比门铃寄存器(REG_UTP_TRANSFER_REQ_DOOR_BELL)和outstanding_reqs的值(异或操作)取得完成的IO请求。对于每个完成的IO请求,调用scsi_done进入scsi 命令的完成处理流程


  • scsi-mq驱动中scsi_done的实现是scsi_mq_done,这个函数会调用blk-mq中的接口blk_mq_complete_request 进入块设备层的request完成处理流程


  • Block Layer对于request完成处理有4种方式,具体如下:


1.对于硬件单队列的块设备,调用__blk_complete_request处理。如果发起IO请求的cpu就是当前cpu或者和当前cpu共享缓存,则发起当前cpu上的block软中断,在block软中断中继续request完成处理流程


2.对于硬件单队列的块设备,如果不满足case 1的条件,则通过IPI(inter-processor interrupt)发起其他cpu上的block软中断,在block软中断继续request完成处理流程


3.对于硬件多队列设备,如果当前cpu与发起IO请求的cpu不共享缓存(且不是高优先级的IO请求),则调用__blk_mq_complete_request_remote发起远端cpu上的request完成处理流程(IPI)


4.对于硬件多队列设备,非上述情况,直接在当前cpu上(硬件中断上下文)继续request完成处理流程


  • 上述4种情况,最后都会调用mq_ops->complete 继续处理request的完成,对于scsi-mq驱动,这个接口的实现是scsi_softirq_done,经过一系列过程调用后(参见图13),由req_bio_endio 完成bio



四、多队列IO调度器



事实上,在blk-mq框架一开始是不支持IO调度器的(Linux-3.13)。由于高速存储器件IO特征是高IOPS,低延迟,我们希望IO的软件开销尽可能低,而IO调度会增加软件开销,所以专门针对这类器件设计的blk-mq在一开始并没有加入IO调度的能力。


当时的Linux块设备层是SQ和MQ两套框架共存的(SQ用于HDD这样的慢速块设备驱动,MQ用于nvme这样的高速块设备驱动)。Linux Block Layer的发展趋势是希望能够使用一套框架同时满足慢速器件和高速器件的需求,所以blk-mq引入后,Linux上的块设备驱动程序开始往MQ框架迁移,在Linux-5.0上,所有基于SQ的块设备驱动都完成了向MQ框架的转化,Block Layer的SQ框架和相关IO调度器被完全移除。


我们知道对于慢速器件(特别是旋转磁盘,随机IO性能很差)来讲,IO调度是十分重要的,同时一些高速器件(特别是硬件单队列的器件,如emmc,ufs)也有IO调度的需求。


因此在Linux-4.11上,Jens Axboe在MQ框架上增加了IO调度的能力,同SQ框架一样,MQ中的IO调度器也是插件化的,框架提供一系列的接口,由具体的IO调度算法(如mq-deadline)实现这些接口:

 


目前基于blk-mq实现的IO调度器主要有下面几个:


  • mq-deadline: 根据IO请求的类型(read/write)分配不同的到期时间(deadline),并将IO请求按照deadline排序,同时支持IO合并,派发时优先选择deadline最小的IO请求,以此来控制IO的延迟。它在Linux-4.11上合入主线,是mq调度器的默认选项。对这个调度器感兴趣的同学可以阅读参考资料8和源码(mq-deadline.c)进一步了解相关细节


  • bfq: budget fair queuing, 它在Linux-4.12上合入主线,主要针对的是慢速器件,如机械硬盘。它提供了IO排序、IO优先级、按权重均匀分配IO带宽和组调度的能力,它保证每个IO的最大延迟可控的同时充分利用器件IO带宽。它的缺点是调度的软件开销比较高,例如Arm CortexTM-A53 8核系统中,最高只能支持80KIOPS,因此不适用于高速器件(如百万级IOPS的SSD)。对这个调度器感兴趣的同学可以阅读参考资料9和源码(bfq-iosched.c)进一步了解相关细节


  • kyber: 它在Linux-4.12上合入主线,是一个真正意义上的mq调度器,适用于高速器件。它对不同类型的IO(read/write/discard/others)设置不同的延迟要求,分开调度,同时监控每个IO调度域的延迟情况,如果某个IO调度域的延迟过高,则动态增加这个IO调度域的队列深度,并减小延迟OK的IO调度域的队列深度,以达到控制IO延迟的目的。本质上这种调度算法倾向于优先调度延迟要求高的IO(如read)。对这个调度器感兴趣的同学可以阅读参考资料10和源码(kyber-iosched.c)进一步了解相关细节



五、结语



本文主要介绍了blk-mq框架,基于这个框架,我们能够实现下面几件事情:


  • 实现基于blk-mq的块设备驱动程序(具体实现可以参考空设备驱动--null_blk)


  • 实现基于blk-mq的IO调度器,例如提供关键IO的优先处理能力、IO限流等(具体实现可以参考kyber-iosched.c)


  • 改进或者扩展blk-mq框架,来达到业务的需求(事实上,在blk-mq演进的过程中,许多想法都来自底层块设备驱动,特别是nvme驱动和scsi-mq驱动)



参考资料


1.《Linux Block IO: Introducing Multi-queue SSD Access on Multi-core Systems》


2.《High Performance Storage with blk-mq and scsi-mq》


3.https://www.thomas-krenn.com/en/wiki/Linux_Multi-Queue_Block_IO_Queueing_Mechanism_(blk-mq)#cite_note-blkmq-2


4.https://lwn.net/Articles/552904/


5.https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/block


6.https://lwn.net/Articles/736534/


7. https://lwn.net/Articles/738449/


8.https://www.kernel.org/doc/html/latest/block/deadline-iosched.html


9.https://www.kernel.org/doc/html/latest/block/bfq-iosched.html


10.https://www.kernel.org/doc/html/latest/block/kyber-iosched.html

1234

路过

雷人

握手

鲜花

鸡蛋

QQ|关于本站|小黑屋|Archiver|手机版|无线电爱好网 ( 粤ICP备15040352号 ) 无线电爱好技术交流5 无线电爱好技术交流1无线电爱好技术交流9开关电源讨论群LED照明应用、电源无线电爱好技术交流4无线电爱好技术交流8无线电爱好技术交流10无线电爱好技术交流11

粤公网安备 44030702001224号

GMT+8, 2022-10-13 10:16 , Processed in 0.124800 second(s), 17 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

返回顶部