VMD: Volume Management Device
英特尔®VMD(卷管理设备)是针对下一代存储推出的部署方案。这套方案支持从 PCIe 总线对 NVMe 固态盘进行热升级和更换,而无需关闭系统,同时标准化 LED 管理可帮助更快速地识别固态盘状态。
NVMe固态盘响应速度更快的原因之一是因为这种类型的盘更接近英特尔处理器上的PCIe总线。在线运维这些固态盘需要系统内核的中断服务处理。借助英特尔VMD,就可以在不用内核中断服务的情况下,在线完成运维任务。
英特尔VMD 是在英特尔至强可扩展处理器的根端口上采用的技术,它将 NVMe 固态盘插入和移除 PCIe 总线事件重定向至存储感知的驱动程序。这些事件先前必须由系统BIOS 和操作系统结合起来进行处理。英特尔VMD 确保从 PCIe总线顺利添加和移除NVMe驱动器,从而确保正常运行时间和可服务性。
由于英特尔VMD技术是较新的技术,需要硬件,系统BIOS和操作系统的协作。如果用户在结合SPDK使用过程中,遇到问题,可以联系英特尔的工程师,或者在SPDK社区提交github issue。
如果想要使用VMD技术,首先要确定处理器是英特尔至强可扩展处理器。然后就可以进入到BIOS里配置VMD。下面以英特尔的至强服务器为例子,介绍如何配置VMD。
开机后,进入BIOS界面,选择Advanced configuration:
然后选择PCI Configuration:
然后选择Volume Management Device, 进入如下页面:
在这个页面中会出现两种配置情况。一种是Oculink,当NVMe固态盘是连接到主板上的Oculink接口上的,那么就需要配置相应的CPU Oculink VMD。在上面的图片中, CPU1 Oculink Volume Management Device(CPU1, IOU3)被打开,其中两个端口都被打开。另外一种情况是PCIe Switch,用户使用PCIe Switch将U.2 NVMe固态盘连接到主板上的转接卡上的插槽上。这种情况下,就要配置正确的Riser和Slot,在上面的图片中,Riser2,Slot2的VMD被打开因为这个端口上接了PCIe Switch。另外一点需要提到的是,如果使用PCIe Switch,需要咨询供应商是否支持VMD功能。
经过以上的配置,相应PCIE槽的VMD功能就被打开了。下面讲解如何使用SPDK VMD模块。
SPDK VMD驱动用来把VMD管理的NVMe固态盘绑定到SPDK的PCIe子系统里。同时也提供LED管理和热插拔API。VMD驱动可以充分利用SPDK现有的软件框架,比如轮询模式,异步操作等。SPDK VMD驱动需要Linux内核的支持,推荐使用4.14以上的内核,或者添加过VMD补丁的内核(比如redhat 3.10.0-693 内核)。同时,如果使用了SPDK VMD功能,一些kernel VMD功能就不能一起使用了,比如VROCs等。SPDK最新的版本20.01开始提供VMD LED和hotplug支持。
使用前,首先检查系统是否正确设置好VMD设备:
$lspci | grep 201d
0000:5d:05.5 RAID bus controller: Intel Corporation Device201d (rev 04)
0000:ae:05.5 RAID bus controller: Intel Corporation Device201d (rev 04)
这个命令输出表示有两个RAID bus controller设备,如果这个命令没有输出,那需要再进入到BIOS确定VMD是否正确的配置。
运行
$PCI_WHITELIST=”0000:ae:05.5 0000:5d:05.5”./scripts/setup.sh
用户也可以添加不属于VMD的NVMe固态盘(BDF)到PCI_WHITELIST, 比如如下命令:
$PCI_WHITELIST=”0000:ae:05.5 0000:5d:05.5 0000:5e:00.0”./scripts/setup.sh
上述命令中0000:5e:00.0是普通的NVMe固态盘,不被VMD管理。
然后运行SPDK vmd工具,得到VMD管理下NVMe 设备的PCI BUS:
#./examples/vmd/lsvmd/lsvmd
5d0505:03:00.0
这里可以看到,虽然系统中有两个RAID bus controller,但是物理配置上,只有一个NVMe SSD由VMD来这里。对应这里的domain ID是相应RAID bus controller的BDF。可以通过这些信息来关联起来。
目前SPDK的perf, identify和fio_plugin 工具支持对VMD设备进行操作。运行perf和identify时,需要加-V参数。运行SPDK fio_plugin时,需要在fio配置文件里加上enable_vmd=1。这部分的作用,都是为了Enable VMD的操作。
以SPDK perf工具为例:
# ./examples/nvme/perf/perf -q 128 -o 4096 -w randread -t 12 -V
Starting SPDK v20.04-pre git sha1 d8aa3ab6b / DPDK 19.11.0initialization...
[ DPDK EAL parameters: perf --no-shconf -c 0x1--log-level=lib.eal:6 --log-level=lib.cryptodev:5 --log-level=user1:6--iova-mode=pa --base-virtaddr=0x200000000000 --match-allocations --file-prefix=spdk_pid26721]
EAL: No available hugepages reported in hugepages-1048576kB
Initializing NVMe Controllers
Attached to NVMe Controller at 5d0505:03:00.0 [8086:0a54]
Associating PCIE (5d0505:03:00.0) with lcore 0
Initialization complete. Launching workers.
========================================================
Latency(us)
Device Information : IOPS MiB/s Average min max
PCIE (5d0505:03:00.0) from core 0: 715544.75 2795.10 178.86 4.04 3428.50
========================================================
Total : 715544.75 2795.10 178.86 4.04 3428.50
VMD设备创建的NVMe块设备同样可以用于SPDK target。下面内容使用RPC命令来配置SPDK vhost。
启动SPDK vhost,等待RPC命令初始化子系统:
$ ./app/vhost/vhost –wait-for-rpc
#运行RPC命令:
#使能VMD驱动
$./scripts/rpc.py enable_vmd
#初始化框架
$ ./scripts/rpc.py framework_start_init
$./scripts/rpc.py bdev_nvme_attach_controller -b NVMe0 -tPCIe -a d70505:03:00.0
$./scripts/rpc.py vhost_create_blk_controller vhost0 NVMe0n1
这样我们就创建了一个vhost控制器,使用VMD下的NVMe固态盘。如果想使用配置文件的话,可以参考附录1,INI配置文件和JSON配置文件都在附录1中。
SPDK 还提供了一个VMD LED管理工具
examples/vmd/led/led,这个工具可以设置VMD管理下的NVMe SSD的状态LED灯的状态。这个工具可以设置四种状态, off, identify, fault和rebuild。Off是LED灯关闭状态。Identify是LED灯以4赫兹的频率闪烁。Fault是led灯一直亮状态。Rebuild是led灯以1赫兹的频率闪烁。该工具还有其他参数,比如打印调试信息,指定设备。如果该命令不带任何参数,那么该命令就会打印当前所有VMD管理下的NVMe设备的LED状态。大家可以通过该命令的帮助信息(./examples/vmd/led/led -h)来运行这个命令。
如果该命令没有实际效果的话,可以运行Linux工具ledctl来调试。Ledctl工具是ledmon软件包里的工具。如果运行ledctl依然没有效果,可以咨询英特尔的工程师。
考虑VMD功能对平台,内核和配置有比较多的依赖,在实际测试和评估中有任何问题,欢迎在微信留言,SPDK社区或者Github SPDK上联系我们。
[VMD]
Enable True
[Nvme]
TransportID"trtype:PCIe traddr:d70505:03:00.0" Nvme0
[VhostBlk0]
Name vhost0
Dev Nvme0n1
JSON配置文件:
{
"subsystems": [
{
"subsystem": "copy",
"config": null
},
{
"subsystem": "interface",
"config": null
},
{
"subsystem": "net_framework",
"config": null
},
{
"subsystem": "vmd",
"config": [
{
"method": "enable_vmd",
"params": {}
}
]
},
{
"subsystem": "bdev",
"config": [
{
"method": "bdev_set_options",
"params": {
"bdev_io_pool_size": 65535,
"bdev_io_cache_size": 256
}
},
{
"method": "bdev_nvme_set_options",
"params": {
"action_on_timeout": "none",
"timeout_us": 0,
"retry_count": 4,
"arbitration_burst": 0,
"low_priority_weight": 0,
"medium_priority_weight": 0,
"high_priority_weight": 0,
"nvme_adminq_poll_period_us": 1000000,
"nvme_ioq_poll_period_us": 0,
"io_queue_requests": 512,
"delay_cmd_submit": true
}
},
{
"method": "bdev_nvme_attach_controller",
"params": {
"name": "Nvme0",
"trtype": "PCIe",
"traddr": "d70505:03:00.0",
"prchk_reftag": false,
"prchk_guard": false
}
},
{
"method": "bdev_nvme_set_hotplug",
"params": {
"period_us": 100000,
"enable": false
}
}
]
},
{
"subsystem": "scsi",
"config": null
},
{
"subsystem": "nbd",
"config": []
},
{
"subsystem": "vhost",
"config": [
{
"method": "vhost_create_blk_controller",
"params": {
"ctrlr": "vhost0",
"dev_name": "Nvme0n1",
"cpumask": "1",
"readonly": false
}
}
]
}
]
}
原文链接:https://mp.weixin.qq.com/s/ajgs7y3AU4fzDKg3cV7Xlw
学习更多dpdk视频
DPDK 学习资料、教学视频和学习路线图 :https://space.bilibili.com/1600631218
Dpdk/网络协议栈/ vpp /OvS/DDos/NFV/虚拟化/高性能专家 学习地址: https://ke.qq.com/course/5066203?flowToken=1043799
DPDK开发学习资料、教学视频和学习路线图分享有需要的可以自行添加学习交流q 君羊909332607备注(XMG) 获取