深入理解nvme hardware queue pair

hardware queue pair是什么

hardware queue pair是我们理解nvme/spdk的牛鼻子,只有深入理解才可能把nvme用好。

从nvme控制器寄存器的角度看

顾名思义,就是一些硬件寄存器组成的队列。

空队列

满队列

  • 问题:
    能否并发入队、出队?不行

submission hardware queue entry

每个entry如下表所示:

  • 入队:

host software 提交命令到tail entry, 通过操作submission hardware queue tail doorbell register;

  • 出队:
    hardware 依次取head entry 去处理

completion hardware hardware queue entry

每个entry的主要fileds 如下:

  • 入队
    hardware 处理完上面取到的nvme command之后,把对应的完成的信息放在completion queue head entry;
  • 出队
    host software 被中断或主动轮询到上面有新的entry 添加之后,去completion queue tail 去取最近提交的命令的处理结果。

这个主要是操作completion queue doorbell 寄存器去实现:

queue pair

nvme控制器内部有多个submission hardware queue,也有多个completion hardware queue。 提交、执行 NVME command的时候,需要使用上面两种hardware queue中的entry,成对使用。

从nvme控制器架构的角度看

hardware queue pair 是抽取"nvme command"的水车。设计到NVME 指令的提交/执行和完成。

概览

下面是一张经典的图:

NVME command提交

NVME已完成命令的处理

spdk对hardware queue pair的封装

IO请求提交函数

  • spdk_nvme_ns_cmd_read
  1. 生产request
    _nvme_ns_cmd_rw(ns, qpair, &payload, ....)
  2. 提交请求
    nvme_qpair_submmit_request()

    2.1 nvme_transport_qpair_submit_request(qpair, request)
    2.1.1 nvme_pcie_qpair_submit_request (qpair, request)
    2.1.1.1 nvme_pcie_qpair_build_contig_request(qpair, req, tr);
    2.1.1.2 nvme_pcie_qpair_submit_tracker(qpair, tr)

nvme_pcie_qpair_submit_tracker(struct spdk_nvme_qpair *qpair, struct nvme_tracker *tr)
{
        struct nvme_request     *req;
        struct nvme_pcie_qpair  *pqpair = nvme_pcie_qpair(qpair);
        struct nvme_pcie_ctrlr  *pctrlr = nvme_pcie_ctrlr(qpair->ctrlr);

        req = tr->req;
        assert(req != NULL);
        req->timed_out = false;
        if (spdk_unlikely(pctrlr->ctrlr.timeout_enabled)) {
                req->submit_tick = spdk_get_ticks();
        } else {
                req->submit_tick = 0;
        }

        pqpair->tr[tr->cid].active = true;

        /* Copy the command from the tracker to the submission queue. */
        nvme_pcie_copy_command(&pqpair->cmd[pqpair->sq_tail], &req->cmd);

        if (spdk_unlikely(++pqpair->sq_tail == pqpair->num_entries)) {
                pqpair->sq_tail = 0;
        }

        if (spdk_unlikely(pqpair->sq_tail == pqpair->sq_head)) {
                SPDK_ERRLOG("sq_tail is passing sq_head!\n");
        }

        spdk_wmb();
        if (spdk_likely(nvme_pcie_qpair_update_mmio_required(qpair,
                        pqpair->sq_tail,
                        pqpair->sq_shadow_tdbl,
                        pqpair->sq_eventidx))) {
                g_thread_mmio_ctrlr = pctrlr;
                spdk_mmio_write_4(pqpair->sq_tdbl, pqpair->sq_tail); // <---
                g_thread_mmio_ctrlr = NULL;
        }
}

通过上面code path可以看到,spdk nvme 需要操作硬件寄存器,并且一路无锁和原子操作。需要上层保护。

IO完成查询函数

spdk_nvme_qpair_process_completions

同上类似操作对应的cq_hdbel,无锁和原子操作,需要上层保护,防止并发修改doorbell 寄存器。

如何用好多个hardware queue pair

需要管理好实际应用中hardware queue pair和线程、处理器核的对应关系,避免多个线程同时访问某个hardware queue。

原文地址:https://blog.51cto.com/xiamachao/2380622

时间: 2024-10-21 23:23:34

深入理解nvme hardware queue pair的相关文章

nvme hardware queue 初始化流程

主要步骤 To setup and initialize I/O Submission Queues and I/O Completion Queues for use, host software follows these steps: Configures the Admin Submission and Completion Queues by initializing the Admin Queue Attributes (AQA), Admin Submission Queue Ba

深入理解nvme协议之二:nvme 协议重点数据结构之间的关系

Physical Region Range(PRP entry) 描述一段物理空间的其实地址和长度,最重要的字段包括: 起始地址(page base address) 偏移大小(offset) 具体如下图所示: Metadata Region 特点:里面的数据不能被split 来传输Metadata may be supported for a namespace as either part of the logical block (creating an extended logical

理解TensorFlow的Queue

https://www.jianshu.com/p/d063804fb272 这篇文章来说说TensorFlow里与Queue有关的概念和用法. 其实概念只有三个: Queue是TF队列和缓存机制的实现 QueueRunner是TF中对操作Queue的线程的封装 Coordinator是TF中用来协调线程运行的工具 虽然它们经常同时出现,但这三样东西在TensorFlow里面是可以单独使用的,不妨先分开来看待. 1. Queue 根据实现的方式不同,分成具体的几种类型,例如: tf.FIFOQu

深入理解SPKD之三:重要API接口

掌握SPDK 常用的API是深入理解SPDK的好方法.下面总结了SPDK 最主要的一些API. 主要的feature列表 spdk/nvme.h Key Functions Description spdk_nvme_probe() Enumerate the bus indicated by the transport ID and attach the userspace NVMe driver to each device found if desired. spdk_nvme_ctrlr

[转帖]深度: NVMe SSD存储性能有哪些影响因素?

深度: NVMe SSD存储性能有哪些影响因素? http://www.itpub.net/2019/07/17/2434/ 之前有一个误解 不明白NVME 到底如何在队列深度大的情况下来提高性能, 现在看来是因为 比AHCI多了 多队列的控制来提高性能. 导读: NVMe SSD的性能时常捉摸不定,为此我们需要打开SSD的神秘盒子,从各个视角分析SSD性能影响因素,并思考从存储软件的角度如何最优化使用NVMe SSD,推进数据中心闪存化进程.本文从NVMe SSD的性能影响因素进行分析,并给出

NVMe over Fabrics又让RDMA技术火了一把

RDMA是个什么鬼?相信大部分不关心高性能网络的童鞋都不太了解.但是NVMe over Fabrics的出现让搞存储的不得不抽出时间来看看这个东西,这篇文章就来介绍下我所了解的RDMA. RDMA(Remote Direct Memory Access)意为在远端直接访问主机的内存,而不需要主机参与.如下图,当主机和Client端都配备RDMA NIC的时候,数据通过NIC的DMA引擎直接在两端内存之间转移,而不需要经过OS的网络协议栈.这种技术对于局域网高带宽的存储系统非常有吸引力. 网络技术

nvme 驱动详解 之1

按照老的套路,在分析一个driver时,我们首先看这个driver相关的kconfig及Makefile文件,察看相关的源代码文件. 在开始阅读一个driver,通常都是从module_init or syscall_init函数看起. 下面让我们开始nvme的旅程吧. 首先打开driver/block下的kconfig文件,其中定义了BLK_DEV_NVME config,如下. config BLK_DEV_NVME tristate"NVM Express block device&quo

浅谈C++ STL queue 容器

浅谈C++ STL queue 容器 本篇随笔简单介绍一下\(C++STL\)中\(queue\)容器的使用方法和常见的使用技巧.\(queue\)容器是\(C++STL\)的一种比较基本的容器.我们在学习这个容器的时候,不仅要学到这个容器具体的使用方法,更要从中体会\(C++STL\)的概念. queue容器的概念 \(queue\)在英文中是队列的意思.队列是一种基本的数据结构.而\(C++STL\)中的队列就是把这种数据结构模板化了.我们可以在脑中想象买票时人们站的排队队列.我们发现,在一

queue(),dequeue()

这两个方法,一个是往里面添加队列,一个是执行队列 也是分静态方法和实例方法, 同样,实例方法最后调用静态方法 源码主要分析一下延迟delay方法,如何起作用的,写的有点仓促,先记录一下 在这里参照了网络上的文章,给推荐一下,介绍的很详细了,作者比较用心: http://www.html-js.com/card/1083,他是基于1.7的,我这边运行的是1.9的,但是核心思想是一样的 jQuery.extend({ queue: function( elem, type, data ) { var