前文我们从使用层面介绍了基于SPDK读写数据的过程,本文将继续深入从NVMe驱动的实现层面介绍一下数据读写的相关内容。在SPDK的NVMe驱动中,两个基本的读写API分别是spdk_nvme_ns_cmd_read和spdk_nvme_ns_cmd_write。这两个API提供基于缓冲区的数据读写,也就是数据是在一段连续的内存缓冲区中。
除了上述基本的API外,SPDK还有一些扩展功能的API,以写数据的API为例,比如支持SGL的spdk_nvme_ns_cmd_writev,以及spdk_nvme_ns_cmd_writev_with_md和spdk_nvme_ns_cmd_writev_ext等函数。本文以基本API spdk_nvme_ns_cmd_read/write为例进行介绍,其他API大同小异,本文不再赘述。
在介绍函数具体实现之前,我们先了解一下NVMe协议读数据的流程,具体如下图所示。在读数据时,NVMe命令会被写入提交队列(1),然后通过门铃通知NVMe控制器命令就绪(2)。NVMe控制器接到就绪通知后会从提交队列读取命令(3),然后进行命令的处理工作(4),具体包括将数据从控制器拷贝到主机内存等。处理完成后通过完成队列通知主机,本文暂时只介绍前半部分。
了解了具体流程,接下来我们详细介绍一下具体实现。如下图是spdk_nvme_ns_cmd_read的原型,其参数包括目的命名空间、IO队列