使用SPDK lib搭建自己的NVMe-oF Target应用

一. 背景

NVMe是一种抽象的传输协议层,旨在提供可靠的NVMe命令和数据传输。NVMe over Fabric (NVMe-oF) 实现了NVMe标准在PCIe总线上的扩展,可以支持数据中心的网络存储,它支持多种传输方式包括FC,RDMA和TCP。NVMe-oF服务(应用) 是SPDK中非常重要的组成部分,也是SPDK感兴趣和使用最多的模块之一。SPDK NVMe-oF 应用已经有很多的文章介绍过它(比如,最近一篇“网络编程的未来,io_uring?”),在20.01版本中,我们增加了NVMe-oF example(下文简写为nvmf)进一步展示它的实现(代码位于 spdk_dir/examples/nvmf/),方便用户的理解和使用,包括搭建自己的NVMe-oF Target应用。

二. 为什么需要nvmf example?

SPDK已经有了NVMe-oF target应用,为什么还要增加一个example呢?主要有以下几点目的:

  1. 更直观的展示SPDK thread的实现。

  2. 展示如何使用SPDK lib 实现一个NVMe-oF target应用。

  3. 快速验证nvmf功能

事实上,SPDK不仅仅提供APP,还提供用户态driver和lib,因此用户也可以根据实际的需求选择直接用我们的APP,还是用SPDK提供的lib自己开发,nvmf example就提供了一个这样的平台,展示如何使用SPDK lib 实现自己的nvmf。

SPDK thread的实现:它是SPDK framework的重要组成部分 [1] ,也是实现SPDK 无锁的基础。事实上,我们已经有一篇微信文章详细介绍了SPDK thread的实现 [2] ,这个example更直观的展示了如何使用SPDK lib实现SPDK thread layer,以及thread的调度算法。

NVMe-oF target的实现:对有些用户而言,他们考虑的更多的是如何把nvmf target集成到自己的APP中。而example展示了如何使用SPDK lib 实现自己的nvmf target.

快速验证:这个特性对用户和开发者而言同样有用。可以利用这个example去快速验证自己对于SPDK thread或者target的一些改进与想法。

三. 剖析nvmf example

3.1 SPDK thread

example演示了如何使用SPDK lib创建自己的thread framework,它的很多实现和SPDK nvmf target非常相似,所以,这也能帮助用户更容易地去理解SPDK 的framework。Example的实现在nvmf_init_threads中,它的实现流程如图1 所示,我们需要先厘清图中一些概念,这样方便用户理解。如果我们把SPDK thread理解成系统中的pthread,那么reactor就可以理解为系统中的core,他负责spdk thread的运行和调度。Reactor的创建会依据APP指定的coremask,然后通过spdk_env_thread_launch_pinned(core, fn, arg)绑定到对应的core上,同时它会指定一个运行函数

SPDK thread的创建主要依赖两个函数

I.spdk_thread_lib_init_ext(thread_op_fn, thread_op_supported_fn, ctx_sz);

II. spdk_thread_create(name, cpumask);

函数1用来初始化thread lib以及指定SPDK thread的调度方法。我们深入去发掘就会发现初始化thread lib其实就是创建thread message pool,因为SPDK thread相互交流通过thread message实现。

函数2用来创建SPDK thread实体,同时它会根据函数1指定的调度函数将thread挂到cpumask指定的reactor上。

总结起来,使用spdk lib创建thread framework分为三步:

  1. SPDK thread lib init并指定thread调度函数

  2. 创建reactor;

  3. 创建SPDK thread;

                                                          图1 SPDK thread

nvmf_init_threads之后,example就可以在SPDK thread上运行,通过spdk_thread_send_msg(thread, fn, arg)让fn去对应的thread上执行。

3.2 NVMe-oF target

NVMe-oF target已经有好几篇微信文章详细介绍过了[3][4][5],example展示的是如何使用SPDK lib创建一个nvmf target。关键函数是nvmf_target_advance_state,它的实现流程如图2所示,nvmf target基于SPDK thread和bdev实现。SPDK thread 已经通过nvmf_init_thread实现了,而spdk_subsystem_init配合makefile可以决定nvmf target支持哪些bdev[6]。关于nvmf target的详细介绍强烈建议阅读《搭建远端存储,深度解读SPDK NVMe-oF target》[5],在这里就不再复述了,通过流程图可以看到nvmf target实现起来并不复杂。这是因为在这里我们只是创建了必须的部分,例如nvmf target实体和discovery subsystem,而其他subsystem和namespace等等,我们统统都是交由RPC的方式去创建的。SPDK正在逐渐去掉配置文件的方式,所以,在这个example中就只支持RPC的方式。RPC的初始化在nvmf_subsystem_init_done,通过 spdk_rpc_initialize和spdk_rpc_set_state实现。

                                                                             图2 Target 初始化流程图

3.3 快速验证

Example都有这样的功能,可以快速地去验证我们的想法。例如example中的thread reschedule。在提交这样的功能之前,可以先在example上实现来说明和验证你的想法,那么别人就可以更清楚地理解你想要实现的功能。当然,反过来也是一样的,实现的功能加入到example中可以让用户更清楚地了解它。

四. 总结

本文通过对nvmf example的剖析,像大家展示了如何使用SPDK lib创建自己的nvmf target应用,希望既能让大家更容易去理解SPDK 的框架也能更清楚如何去使用SPDK lib。

原文链接https://mp.weixin.qq.com/s/niKa3wnlRuz4LJ47mJBJvQ

学习更多dpdk视频
DPDK 学习资料、教学视频和学习路线图 :https://space.bilibili.com/1600631218
Dpdk/网络协议栈/ vpp /OvS/DDos/NFV/虚拟化/高性能专家 上课地址: https://ke.qq.com/course/5066203?flowToken=1043799
DPDK开发学习资料、教学视频和学习路线图分享有需要的可以自行添加学习交流q 君羊909332607备注(XMG) 获取
 

相关文章

显卡天梯图2024最新版,显卡是电脑进行图形处理的重要设备,...
初始化电脑时出现问题怎么办,可以使用win系统的安装介质,连...
todesk远程开机怎么设置,两台电脑要在同一局域网内,然后需...
油猴谷歌插件怎么安装,可以通过谷歌应用商店进行安装,需要...
虚拟内存这个名词想必很多人都听说过,我们在使用电脑的时候...