Linux 3.19内核block层增加了multi-queue block layer,对 NVMe的多队列特性的支持实现了从无到有,并越来越成熟。以MySQL数据库场景为例,借助NVMe SSD + linux Blk-mq,将不同的Block层提交队列分配到不同的CPU核上,更好的平衡IO的工作负载,可以大幅提升NVMe SSD处理IO的效率。 MySQL 的Sysbench OLTP测试结果(NVMe...
这个函数初始化nvme盘的admin和io队列(struct nvme_queue),同时初始化nvme盘的管理队列和请求队列对应的硬件队列描述结构blk_mq_tag_set,注意:这里的请求队列结构是struct request_queue,并不是nvme盘收发命令的admin和io队列,每个nvme逻辑盘只有一个请求队列,一个该请求队列对应多个nvme盘硬件io队列。nvme逻辑盘用stru...
System crash in blk_mq_free_request() following NVMe controller reset due to NULL mq_hctx. Example 1: Raw nvme nvme0: I/O 71 QID 1 timeout, aborting nvme nvme0: Abort status: 0x0 nvme nvme0: I/O 71 QID 1 timeout, reset controller nvme nvme0: 2/0/0 default/read/poll queues...
static struct request *nvme_alloc_user_request(struct request_queue *q, struct nvme_command *cmd, blk_opf_t rq_flags, blk_mq_req_flags_t blk_flags) { struct request *req; req = blk_mq_alloc_request(q, nvme_req_op(cmd) | rq_flags, blk_flags); if (IS_ERR(req)) return req; ...
blk-mq-sysfs.c生成了一些其他的nvme的统计项, 有多少个online的cpu,在驱动加载的时候会默认生成多少个队列,除非内存不足或者在保留内核中,则会减少。 [root@localhost mq]# ls0 10 12 14 16 18 2 21 23 25 27 29 30 32
比如上图中的“blk_mqscsi_mod”,就让我想起5年前写过的《突破百万IOPS:blk-mq释放SCSI性能》。 更多细节我就不在此都粘贴过来了,大家可以参考报告原文档。以上信息不仅使测试报告更加客观(因为各项结果按照同样配置和操作要能复现),同时对技术爱好者们学习也有帮助。 PERC 11 RAID卡和PowerEdge 15G服务器 最后...
从下面火焰图的结果中也可以清晰的看到NVMe使用了 blk-mq-make-request 多队列调用;而SATA只能调用原有的单队列。SATA只能支持单队列IO操作(generic_make_request)的问题被这个场景鲜明的展示了出来。 NVMe SSD的高并发与多核CPU结合使得系统性能有了质的提升。从RocksDB的角度讲,LSM数据结构在高频read的时候会触发...
static int nvme_alloc_admin_tags(structnvme_dev *dev) { //初始化admin_q为null,故进入if分支 //初始化blk_mq_tag_set结构体,nvme_mq_admin_ops在run request会用到 ;//hardware queue个数为1 dev->admin_tagset.queue_depth = NVME_AQ_DEPTH -1; dev->admin_tagset.timeout = ADMIN_TIMEOUT; ...
structblk_mq_tags **tags; dma_addr_t sq_dma_addr; dma_addr_t cq_dma_addr; u32 __iomem *q_db; u16 q_depth; s16 cq_vector; u16 sq_tail; u16 cq_head; u16 qid; u8 cq_phase; u8 cqe_seen; u32 *dbbuf_sq_db; u32 *dbbuf_cq_db; ...
blk_mq_complete_request(req, le16_to_cpu(cqe.status)>>1); }if(head == nvmeq->cq_head && phase == nvmeq->cq_phase)return0;if(likely(nvmeq->cq_vector >=0)) writel(head, nvmeq->q_db + nvmeq->dev->db_stride); nvmeq->cq_head =head; ...