首页 > 编程语言 >SPDK源码剖析一hello_world程序

SPDK源码剖析一hello_world程序

时间:2024-08-15 16:25:20浏览次数:11  
标签:队列 NVMe spdk SPDK 源码 world CQ SQ

SPDK初识之hello_world程序分析

首先是hello_world程序整体框架分析
在这里插入图片描述

int main(int argc, char **argv)
{
    
    rc = parse_args(argc, argv, &opts);
     
    if (spdk_env_init(&opts) < 0) {  // spdk环境初始化,最终调用dpdk环境初始化
    }

    // 扫描设备,将驱动和设备绑定,调用回调函数`probe_cb`和`attach_cb`
    rc = spdk_nvme_probe(&g_trid, NULL, probe_cb, attach_cb, NULL); 

    hello_world(); // IO qpair创建、nvme的读写
    cleanup();  

    return rc;
}

初始化SPDK环境

int spdk_env_init(const struct spdk_env_opts *opts)

函数 spdk_env_init 用于初始化SPDK环境,它接受一个指向 spdk_env_opts 结构体的指针作为参数。这个结构体包含了SPDK环境配置的各种选项。在调用 spdk_env_init 之前,通常需要先通过 spdk_env_opts_init 函数来初始化这个结构体,设置一些基本的配置选项。
最终调用DPDK的接口rte_eal_init来完成SPDK环境的初始化。

扫描设备

SPDK对于传输使用的协议或者总线虚拟化成一个transport,主要包含PCIE、TCP、Fabric、RDMA等类型。
SPDK对设备的管理类似Linux的设备驱动模型:包含总线、设备、驱动三个部分。
SPDK先后注册总线、驱动和transport。
之后提供了两个回调接口。

两个回调接口

probe_cb:
probe_cb 是在SPDK发现新的NVMe控制器后调用的回调函数。
在hello_world示例中,当SPDK发现一个新的NVMe控制器时,它仅打印了一条日志消息来确认控制器的发现。

attach_cb:
attach_cb 是在NVMe控制器成功连接到用户空间驱动程序后调用的回调函数。
在hello_world示例中,attach_cb 做了两件事情:
将初始化好的NVMe控制器添加到全局控制器列表 g_controllers 中,以便SPDK可以跟踪和管理所有已发现的控制器。
将命名空间(Namespace,NS)注册到控制器中。在NVMe中,命名空间是逻辑存储单元,它包含存储设备上的数据。注册命名空间意味着SPDK可以开始对它进行操作。

Qpair

首先明白SPDK中的关键概念:提交队列(Submission Queue)和完成队列(Completion Queue)
在NVMe(非易失性内存表达)协议中,SQ和CQ是两个关键的概念,用于管理NVMe设备上的I/O(输入/输出)操作。

SQ: SQ是NVMe设备上的一个队列,用于存放待处理的I/O请求。 主机(HOST)将I/O请求打包成命令,并放入SQ中。 NVMe子系统会从SQ中读取命令,并处理这些I/O请求。

CQ: CQ是NVMe设备上的另一个队列,用于存放处理完成的I/O请求。当NVMe子系统完成一个I/O请求时,它会生成一个完成命令,并将其放入CQ中。 主机从CQ中读取完成命令,以确认I/O操作的成功或失败。

在NVMe协议中,SQ和CQ的个数并没有要求一一对应。也就是说,一个SQ可以对应多个CQ,或者一个CQ可以对应多个SQ。这种设计增加了系统的灵活性,可以根据具体需求配置SQ和CQ的数量。

然而,在SPDK中,SQ和CQ通常是一一对应的,并且都包含在一个名为“qpair”的结构中。这种做法简化了SPDK的编程模型,使得开发者可以更容易地管理和同步I/O请求的提交和完成

QPair是SPDK(Storage Performance Development Kit)中的一种结构,用于管理NVMe(非易失性内存表达)设备的I/O操作。如下图所示:
在这里插入图片描述
QPair包括两个主要部分:SQ(Submission Queue,提交队列)和CQ(Completion Queue,完成队列)。
为了更有效地管理请求对象,每个QPair都会包含一个free_req对象池,用于缓存nvme_request对象实例。同时,还会包含一个free_tr对象池,用于缓存nvme_tracker对象,每个对象都关联一个cmdId(命令标识),以跟踪每个请求的执行情况。当请求完成时,相应的回调会被触发。

nvme_request对象内部主要维护了spdk_nvme_cmd数据结构,由于SQ和CQ使用不同的物理内存空间,因此在提交命令时需要进行一次数据拷贝。

对于执行失败的请求,QPair不会直接丢弃它们,而是先加入到queued_req队列中,以便后续进行重试处理。当queued_req队列不为空时,新的请求会先提交到这个队列中,确保之前失败的请求先得到处理。

在SPDK中,每个QPair(队列对)会绑定两个Doorbell寄存器,每个寄存器占用4个字节的空间。这些寄存器用于通知NVMe控制器关于I/O操作的状态,并且基于基于MMIO(内存映射I/O)方式更新。具体来说:
第一个Doorbell寄存器用于告知NVMe控制器,提交队列(SQ)中新的I/O命令已准备好执行。
第二个Doorbell寄存器用于通知NVMe控制器,完成队列(CQ)中I/O命令的执行状态已更新。

IO处理

创建IO qpair

创建IO qpair时先创建CQ再创建SQ。

IO读写

SPDK的命令在执行前,每个命令都会附带一个完成后的回调函数。这意味着一旦命令完成并收到对应的完成队列条目(CQE),就会触发这个回调函数。
因此,Hello_world示例利用了这一特性,实现了先写入数据再读取的操作流程。在发送写命令时,它定义了一个回调函数write_complete,并在该函数内部执行了NVMe的读操作,在发送读命令时,定义一个回调函数read_complete,在该函数内部打印数据,并将sequence.is_completed标志设置为1。

在Hello_world函数里,主程序一个while死循环,在循环体内周期性地调用spdk_nvme_qpair_process_completions() 函数。
这个函数会检查NVMe设备的完成队列(CQ),以确定是否有新的完成事件(CQEs)到达。
如果CQ中有新的完成事件,函数会处理这些事件,并调用相应的回调函数。在Hello_world示例中回调函数将sequence.is_completed标志位设置为1,于是死循环退出

//轮询I/O队列对,等待写操作完成
		while (!sequence.is_completed) {
			spdk_nvme_qpair_process_completions(ns_entry->qpair, 0);
		}

标签:队列,NVMe,spdk,SPDK,源码,world,CQ,SQ
From: https://blog.csdn.net/qq_51350957/article/details/141198374

相关文章

  • [开题报告]FLASK框架物业信息管理系统6ejy0(源码+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着城市化进程的加快和居民生活品质的提升,物业管理已成为现代社区不可或缺的一部分。然而,传统的物业管理方式往往依赖于纸质记录和人工处......
  • [开题报告]FLASK框架鲜花坊销售平台19bw3(源码+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着教育信息化的不断深入,高校教学管理逐渐向数字化、智能化转型。西安文理学院作为一所致力于提升教学质量与效率的学府,其教学进度管理面......
  • ThreadLocal源码解析
    ThreadLocal有内部类ThreadLocalMap,ThreadLocalMap是ThreadLocal的核心1.每个线程下的有一个ThreadLocalMapstaticclassThreadLocalMap{staticclassEntryextendsWeakReference<ThreadLocal<?>>{Objectvalue;Entry(ThreadLocal<?>k,Ob......
  • 编写Hello, world!
    Hello,world随便新建一个文件夹,存放代码新建一个Java文件文件后缀名为.javaHello.java【ps】系统可能没有显示文件名编写代码publicclassHello{ publicstaticvoidmain(String[]args){ System.out.print("Hello,world!"); }}编译javacjava文......
  • Java、python、php版的宠物美容预约服务系统的设计与实现 (源码、调试、LW、开题、PPT)
    ......
  • 本地生活服务平台源码在哪里找到?获取全攻略来了!
    随着本地生活的市场前景和收益空间不断显现,各大官方平台的本地生活服务商申请门槛和审核力度以及入局后的考核要求也在持续调高。在此背景下,越来越多的创业者开始想要通过搭建本地生活服务平台源码完成入局,连带着本地生活服务平台源码在哪里找到等相关问题也因此备受关注。而......
  • 全平台7合一DIY小程序源码系统,一个系统全部搞定 带完整的安装代码包以及搭建部署教程
    系统概述全平台7合一DIY小程序源码系统,是一款集成了目前市场上主流七大平台(包括但不限于微信、支付宝、百度、字节跳动、QQ、京东、快应用)小程序开发能力的综合性源码解决方案。该系统采用模块化设计,支持快速定制与灵活扩展,让企业和开发者无需再为不同平台的小程序开发而烦恼,......
  • 智能名片电子小程序源码系统 附带源码包以及搭建部署教程
    系统概述智能名片电子小程序源码系统,是一款基于最新互联网技术和人工智能算法开发的创新产品。它打破了传统名片的信息传递限制,将个人或企业的基本信息、产品展示、动态更新、在线交流等功能融为一体,通过微信、支付宝等主流平台的小程序形式展现,实现了一站式、多维度的商务信......
  • 基于PHP+MySQL组合开发的同城二手市场便民小程序源码系统 带完整的安装代码包以及搭建
    系统概述随着消费观念的转变和环保意识的增强,越来越多的人开始选择二手商品作为消费首选。然而,传统的二手交易方式往往存在信息不对称、交易效率低下等问题,严重制约了二手市场的发展。因此,开发一款集信息发布、搜索浏览、在线沟通、安全交易于一体的同城二手市场小程序,显得尤......
  • 万能分销商城小程序源码系统 带完整的安装代码包以及搭建部署教程
    系统概述随着移动互联网的普及,小程序成为了人们生活中不可或缺的一部分。企业和商家们逐渐意识到,拥有一个自己的分销商城小程序能够带来巨大的商业价值。然而,从零开始开发一个功能完备的分销商城小程序需要耗费大量的时间、人力和物力。为了解决这一问题,万能分销商城小程序源......