如何为NVMe禁用blk-mq并使用CFQ、deadline、noop调度器?
关于NVMe驱动器使用传统非blk-mq调度器的可行性说明
首先直接给结论:你无法让NVMe驱动器使用传统的非blk-mq版本CFQ、deadline或noop调度器,原因很简单——NVMe驱动从设计之初就完全基于blk-mq(多队列块IO框架)开发,它没有适配老的单队列块IO框架,传统调度器根本无法与NVMe驱动进行交互。
你提到给SATA SSD添加scsi_mod.use_blk_mq=1来启用blk-mq,但NVMe的情况正好相反:它默认就使用blk-mq,而且没有“反向操作”的选项,因为整个驱动架构都依赖这个框架,不存在回退到非blk-mq的路径。
不过,如果你只是想测试类似这些调度器的IO调度行为,还是有替代方案的:blk-mq生态里有对应的兼容版本调度器,比如:
mq-deadline:对应传统的deadline调度器,是blk-mq下的官方实现noop:blk-mq版本的noop和传统版本行为几乎一致,适合测试无调度的场景- 另外还有
kyber(针对低延迟优化)、bfq(类似CFQ的公平调度,需要额外启用)这类blk-mq调度器
操作步骤(测试blk-mq调度器)
查看NVMe设备当前可用的调度器
先找到你的NVMe设备名(通常是nvme0n1、nvme1n1这类),然后执行:cat /sys/block/nvme0n1/queue/scheduler输出中带
[]的就是当前正在使用的调度器。切换到目标调度器
比如要切换到mq-deadline,执行:echo mq-deadline | sudo tee /sys/block/nvme0n1/queue/scheduler切换后再执行第一步的命令确认是否生效。
永久生效(可选)
如果想让调度器设置在重启后保持,可以编辑/etc/udev/rules.d/60-io-scheduler.rules文件,添加类似规则:ACTION=="add|change", KERNEL=="nvme0n1", ATTR{queue/scheduler}="mq-deadline"保存后重启系统即可。
需要注意的是,传统的CFQ没有对应的blk-mq版本,因为它的单队列设计和NVMe的多队列架构不匹配。如果需要类似CFQ的公平调度行为,可以尝试bfq调度器(部分发行版需要安装额外内核包或启用对应的内核配置)。
内容的提问来源于stack exchange,提问作者Jared Gillespie




