剖析SPDK读写NVMe盘过程--从hello_world开始

1

概述

本文基于SPDK v22.09(点击蓝字,阅读往期文章),从hello_world程序来剖析SDPK NVMe用户态驱动,对NVMe盘的初始化、管理和读写操作。

spdk/examples/nvme/hello_world.c整体结构代码:

59f6db1db80025c71b9da84fdd061f48.png

图1显示了NVMe子系统和CPU以及内存设备之间的结构,这对于我们理解spdk[MX1] 的IO过程很有帮助。Qpair一般创建于内存中,nvme子系统作为一个pCIe endpoint通过pCIe总线挂接。接下来我们关注的是nvme子系统如何基于nvme协议,通过pCIe总线实现和HOST的通信以及它们之间进行通信的细节。本文将重点关注于设备的查找和绑定以及IO详细处理过程。

aa16c63850cc4d8b746d748e15efb820.png

图1. NVMe子系统体系结构

2

设备查找

我们的重点部分是扫描设备并将设备和控制器绑定以及数据的读写操作。下面进行具体分析怎么扫描设备并和驱动绑定的。两个重要的回调函数probe_cb和attach_cb。

probe_cb:找到NVMe controller之后进行回调。

attach_cb:一旦NVMe控制器已连接到用户空间驱动程序后调用。

图2展示了spdk_nvme_probe函数的调用过程。

196fe4eef45a16c2fafbb650a634113d.png

图2. 设备查找流程

在spdk_nvme_probe函数指明了transport id。调用spdk_nvme_probe_async,这是一个异步函数,函数中我们重点关注对于spdk_nvme_probe_async函数的调用。

spdk_nvme_probe_async函数实现了对于在nvme_driver_init函数中对全局变量g_spdk_nvme_driver进行初始化,由于是对全局变量进行操作,故要进行加锁操作。我们看一下在锁之间进行了哪些事情。首先进行主进程判断,只有主进程中的一个线程可以进行驱动的初始化,并维护一个共享内存。其他进程将会查找已存在的共享内存。在对g_spdk_nvme_driver初始化之后就可以使用g_spdk_nvme_driver内部持有的锁而将前面持有的锁释放掉。

g_spdk_nvme_driver是全局变量可以被多个进程访问,内部维护了一个多进程共享的队列,队列维护了已经和驱动绑定的控制器。

然后我们进行到nvme_probe_internal(probe_ctx, false),在这个函数里进行具体的设备查找工作。在nvme_transport_ctrlr_scan(probe_ctx, direct_connect)函数中,会在return时调用nvme_pcie_ctrlr_scan(probe_ctx, direct_connect),在nvme_pcie_ctrlr_scan函数中调用了函数spdk_pci_enumerate(spdk_pci_nvme_get_driver(),pcie_nvme_enum_cb, &enum_ctx),实现按照给定的驱动进行设备的枚举,并尝试将没有绑定驱动的设备绑定到驱动上。这里传入了一个回调函数,pcie_n

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值