SPDK源码剖析一hello_world程序

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);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/400926.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bluecmsphp代码审计

bluecms代码审计 (一) 运行环境需求&#xff1a; 可用的 httpd 服务器&#xff08;如 Apache、Zeus、IIS 等&#xff09; PHP 4.3.0 及以上 MySQL 4.1 及以上配置文件审计 看到uploads/install/include/common.inc.php 当然我们可能自己根本不知道那个是重要的文件&#x…

C++《类和对象》(上)

在之前的C入门基础知识中我们了解了C的发展过程已经重要性&#xff0c;还初步了解了C中一些相比C语言特有的知识点&#xff0c;例如命名空间、缺少参数、函数重载、引用等&#xff0c;接下来在本篇中我们将开始C整个体系中非常重要的一个知识章节——类和对象&#xff0c;类和对…

Unity新输入系统 之 InputActions(输入配置文件)

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正​ 首先你应该了解新输入系统的基本单位Unity新输入系统 之 InputAction&#xff08;输入配置文件最基本的单位&#xff0…

React 学习——react项目中加入echarts图

实现的代码如下&#xff1a; import * as echarts from echarts import { useEffect, useRef } from react; const Home ()>{const chartRef useRef(null);useEffect(()>{// const chartDom document.getElementById(main);//使用id获取节点const chartDom chartRef…

【区块链+乡村振兴】“蜜链盟”乡村振兴基层治理数字化平台 | FISCO BCOS应用案例

在国家战略政策推动和新一代信息化发展应用的合力之下&#xff0c;数字乡村是互联网化、信息化和数字化在农业农村经 济社会发展中的表现。为进一步加强乡村基层治理&#xff0c;根据《中共海南省委农村工作领导小组办公室海南省农业农 村厅关于在我省乡村治理中推广运用积分制…

用exceljs和file-saver插件实现纯前端表格导出Excel(支持样式配置,多级表头)

exceljs在Jquery&#xff08;HTML&#xff09;和vue项目中实现导出功能 前言Jquery&#xff08;HTML&#xff09;中实现导出第一步&#xff0c;先在项目本地中导入exceljs和file-saver包第二步&#xff0c;封装导出Excel方法&#xff08;可直接复制粘贴使用&#xff09;第三步&…

Java 实现 B树(通俗易懂)

目录 一.概念 二.节点定义 三.插入操作 1.查找位置 2.插入 3.分裂 四.B树和B*树 1.B树 2.B*树 一.概念 B树是一颗多叉平衡树&#xff0c;空树也是多叉平衡树。 一颗M阶的B树要满足以下条件&#xff1a; 1.根节点至少有两个孩子&#xff1b; 2.每个非根节点至少有(上…

机械学习—零基础学习日志(如何理解线性代数2)

零基础为了学人工智能&#xff0c;正在快乐学习&#xff0c;每天都长脑子 引言 在平面中&#xff0c;直线的定义可以理解为&#xff0c;任意缩放同一个平面向量得到所有点的集合。 所以要得到一个三维空间中的直线&#xff0c;只需要将这个向量改成三维向量即可。 什么是线…

uniapp加载第三方字体方案对比(附原生微信小程序方案)

文章目录 官方文档uniapp文档微信小程序文档 下载字体包引入方案限制微信小程序限制uniapp的限制 方案对比方案1&#xff1a;CSS本地加载方案2&#xff1a;CSS远程加载方案3&#xff1a;转换为base64&#xff0c;然后通过css引入方案4&#xff1a;使用uni.loadFontFace() 页面使…

(Jmeter、Fiddler)脚本转换Loadrunner脚本

背景&#xff1a;公司政治任务、各种体系文档要留档&#xff0c;但有些不在体系内的工具生成的脚本需要转化到体系内以备留档。 一、Loadrunner代理设置 开始录制配置&#xff1a; Record->Remote Application via LoadRunner Proxy LoadRrunner Proxy listens on port-…

米联客-FPGA程序设计Verilog语法入门篇连载-19 Verilog语法_低功耗设计

软件版本&#xff1a;无 操作系统&#xff1a;WIN10 64bit 硬件平台&#xff1a;适用所有系列FPGA 板卡获取平台&#xff1a;https://milianke.tmall.com/ 登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑&#xff01; 1概述 本小节讲解Verilog语法的低功…

Spark MLlib 特征工程(下)

Spark MLlib 特征工程(下) 前面我们提到&#xff0c;典型的特征工程包含如下几个环节&#xff0c;即预处理、特征选择、归一化、离散化、Embedding 和向量计算&#xff0c;如下图所示。 在上一讲&#xff0c;我们着重讲解了其中的前 3 个环节&#xff0c;也就是预处理、特征选…

java---概念

一.配置环境&#xff08;三个变量&#xff09; 1.JAVA_HOME&#xff08;记录Java安装文件的路径&#xff09; 2.PATH&#xff08;系统直找的路径&#xff09; 3.CLASSPATH&#xff08;Java程序路径&#xff09; .;%JAVA_HOME%\lib 二.第一个Java程序 源代码&#xff1a; so…

使用kimi快速完成论文仿写的提示词,我帮你总结好了

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 在完成论文写作时&#xff0c;很多人都会想到“仿写”&#xff0c;但正确的做法是借鉴而非复制。今天我们将分享如何利用Kimi智能助手来提高论文写作的效率和质量&#xff0c;同时确保原…

Kubernetes快速入门

一、容器集群管理概述 1.1背景概述 容器技术的诞生虽解决了应用打包和发布的难题&#xff0c;但单一的容器技术工具并无 法支持起生产级大规模容器部署的场景。针对这一场景&#xff0c;容器管理与编排成为了容器技术发展的关键。Kubernetes 便是在这样的大背景下诞生的。 1.2…

【博客23】缤果Android_XXX调试助手模板(3款)V1.0(中级篇)

超级好用的Android_XXX调试助手模板 ( Android Studio Java) 备注: 仅模板无通信协议 开发工具: android-studio-2024.1.1.12-windows.exe 目录 一、软件概要&#xff1a; 二、软件界面&#xff1a; 1.App演示 2.其他扩展展示 2.1 自定义指令集 2.2 修改自定义指令集 …

IAM 编程访问和 AWS CLI

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; IAM 编程访问&#xff08;欢迎来到雲闪世界。&#xff09; IAM 编程访问是指使用访问密钥通过 API 和命令行工具访问 AWS 服务和资源。 当您为 IAM 用户启用编程访问时&#xff0c;您将生成可用于验证和…

Java-自定义注解中成员变量是Class<?>

在Java中,自定义注解可以包含各种类型的成员变量,包括 Class<?> 类型。这种类型的成员变量 通常用于表示某个类的类型信息。下面我将详细介绍如何定义一个包含 Class<?> 类型成员变量的 自定义注解,并给出一些示例代码。 1. 定义自定义注解 定义一个自定义…

行业大模型:信用评分大模型、生产优化大模型、库存管理大模型、物流行业大模型、零售行业大模型

金融行业大模型&#xff1a;信用评分大模型 信用评分模型在金融行业中扮演着至关重要的角色&#xff0c;它通过对个人或企业的信用状况进行评估&#xff0c;帮助金融机构有效控制风险&#xff0c;提高业务效率。以下是信用评分模型的特点及案例介绍&#xff1a; 信用评分模型…

高阶数据结构——B树

1. 常见的搜索结构 以上结构适合用于数据量相对不是很大&#xff0c;能够一次性存放在内存中&#xff0c;进行数据查找的场景。如果数据量很大&#xff0c;比如有100G数据&#xff0c;无法一次放进内存中&#xff0c;那就只能放在磁盘上了&#xff0c;如果放在磁盘上&#xff0…