Linux NVMe驱动用户态指定IO队列的配置正确性咨询
NVMe驱动定制的配置正确性疑问
我正在基于Linux 6.5内核(Ubuntu 22)定制NVMe驱动,使其在NVME_IOCTL_SUBMIT_IO的ioctl命令中接收QID,并将IO命令提交到指定的QID。
调用流程
nvme_ioctl -> nvme_ns_ioctl -> nvme_submit_io -> nvme_submit_user_cmd_qid(已修改) -> nvme_alloc_user_request_qid(已修改)
最终会调用:
req = blk_mq_alloc_request_hctx(q, (nvme_req_op(cmd) | rq_flags), (blk_flags | BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_RESERVED), qid - 1);
使用用户传入的QID。
在队列初始化的nvme_alloc_io_tag_set中,我在set->nr_hw_queues = ctrl->queue_count - 1;之后设置了:
set->reserved_tags = set->nr_hw_queues;
当前该配置下可正常执行IO,且跟踪点中也能看到对应的QID。
请问我设置reserved_tags和调用blk_mq_alloc_request_hctx()的配置是否正确?
我做此定制的原因有两点:
- 需控制QID以进行压力测试(客户需求)
- 提升性能:默认每个CPU分配一个队列,即使存在多队列也未全部利用,可通过指定QID将不同命令分配到不同队列。
配置正确性分析
1. blk_mq_alloc_request_hctx()调用的正确性
你的调用是正确的:
- 该函数第四个参数为硬件队列索引(hctx_idx),NVMe控制器IO队列通常从1开始编号,而blk-mq的硬件队列索引从0起始,传入
qid - 1完全符合编号规则。 - 你添加了
BLK_MQ_REQ_RESERVED标志,配合reserved_tags的设置,能让这类指定QID的请求使用独立预留的tag池,避免和普通IO请求的tag资源冲突。
2. reserved_tags设置的合理性
reserved_tags的作用是为带BLK_MQ_REQ_RESERVED标志的请求预留独立tag资源,防止普通IO耗尽所有tag导致这类指定QID的请求无法分配。你的设置set->reserved_tags = set->nr_hw_queues是合理的:
- 这个值保证每个硬件队列至少有一个预留tag可用,完全满足你指定QID提交IO的需求。
- 结合你的定制场景(用户指定QID做压力测试或性能优化),这类请求的并发量不会无限制增长,该预留量既足够支撑需求,也不会过度占用系统资源。
额外注意事项
- 必须添加QID合法性校验逻辑:在
nvme_submit_user_cmd_qid中检查用户传入的QID是否在1~ctrl->queue_count范围内,避免因索引越界引发内核错误。 - 若后续需要支持更高并发的指定QID IO,可根据实际压力调整
reserved_tags大小,比如为每个队列预留多个tag。
内容的提问来源于stack exchange,提问作者Sharma PV
相关产品推荐
相关产品推荐

