Cloud Hypervisor vDPA 使用指南:以 virtio 数据面加速实现接近裸机的设备透传与可迁移性
【免费下载链接】cloud-hypervisorA Virtual Machine Monitor for modern Cloud workloads. Features include CPU, memory and device hotplug, support for running Windows and Linux guests, device offload with vhost-user and a minimal compact footprint. Written in Rust with a strong focus on security.项目地址: https://gitcode.com/GitHub_Trending/cl/cloud-hypervisor
vDPA(Virtio Data Path Acceleration)是 Cloud Hypervisor 中用于将符合 VIRTIO 规范的硬件设备以接近裸机性能透传给虚拟机的技术方案,其核心价值在于数据面(virtqueue)由硬件与 Guest 直接通过 DMA 交互,而控制面由内核 vDPA 框架以 vhost-vdpa 设备形式暴露给 VMM,从而在不依赖厂商专用迁移框架的前提下实现设备的可迁移性。本文以 Cloud Hypervisor 的--vdpa参数为主线,完整讲解 vDPA 的工作原理、VdpaConfig全部参数语义、基于内核 vDPA 模拟器的端到端配置步骤,并结合 VdpaConfig 源码实现 与 vhost-vdpa 设备驱动 说明底层机制,读者读完即可在实际宿主机上完成 vDPA 设备的配置、验证与排障。
vDPA 技术原理:VFIO 之外的另一条透传路径
vDPA 旨在让传入虚拟机的设备获得接近裸机的性能,它是 VFIO 之外的一种替代方案:相比 VFIO,vDPA 提供了一条更简单的实现设备迁移的路径。
从内核框架角度看,vDPA 是一个相对较新的内核框架,用于处理那些在**数据面(data-path)上遵循 VIRTIO 规范的设备,而其控制面(control-path)**则由厂商自定义实现。具体来说:
- 数据面:virtqueue 通过硬件与 Guest 之间的 DMA 机制被直接访问,IO 路径上几乎没有软件模拟开销,这是获得接近裸机性能的关键;
- 控制面:通过 vDPA 框架访问,该框架以 vhost 接口的形式将设备暴露为vhost-vdpa设备(即
/dev/vhost-vdpa-X)。
正是因为设备与 Guest 之间的 DMA 访问都经由 virtqueue 完成,迁移可以在不要求设备驱动实现任何特定迁移支持的情况下达成。而 VFIO 方案则不同:每个厂商都需要为 VFIO 迁移框架提供一套实现,且这套实现必须针对每个设备驱动逐一完成,复杂度明显更高。这也是 vDPA 在设备迁移场景中被重点考虑的原因。
在 Cloud Hypervisor 中,vDPA 设备的接入由virtio-devicescrate 中的 vdpa.rs 实现:它通过vhost::vdpa::VhostVdpa与内核 vhost-vdpa 后端(vhost::vhost_kern::vdpa::VhostKernVdpa)交互,完成 DMA 映射(DmaMap/DmaUnmap)、IOVA 范围查询(GetIovaRange)与虚拟队列配置(VringConfigData)等操作。从该文件的错误枚举可以看到几个关键约束,例如:
InvalidIovaRange:设备返回的 IOVA 范围非法;Missing VIRTIO_F_ACCESS_PLATFORM feature:后端必须支持VIRTIO_F_ACCESS_PLATFORM特性,这是 vDPA 设备走 DMA 直通、需要 IOMMU 地址翻译的前提;- 同时源码中还引用了
VHOST_BACKEND_F_SUSPEND,用于迁移过程中的队列挂起/恢复。
--vdpa命令行参数与VdpaConfig结构
vDPA 设备在 Cloud Hypervisor 中的配置载体是VdpaConfig,从 CLI 角度即--vdpa参数。该结构定义于 vmm/src/vm_config.rs:
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct VdpaConfig { #[serde(flatten)] pub pci_common: PciDeviceCommonConfig, pub path: PathBuf, #[serde(default = "default_vdpaconfig_num_queues")] pub num_queues: usize, }其中pci_common以serde(flatten)方式内联了 PCI 设备的公共配置(id、iommu、pci_segment、pci_device_id),num_queues的默认值由default_vdpaconfig_num_queues()提供,即1。命令行帮助信息中的完整语法为:
--vdpa <vdpa> vDPA device "path=<device_path>,num_queues=<number_of_queues>,iommu=on|off,id=<device_id>,pci_segment=<segment_id>,pci_device_id=<pci_slot>"对应到源码,VdpaConfig::parse(vmm/src/config.rs)的解析逻辑是:path为必填项(缺失时直接报ParseVdpaPathMissing错误),num_queues为可选项并默认取1,其余选项委托给PciDeviceCommonConfig::parse(vmm/src/config.rs)统一处理。仓库中还提供了对应的单元测试test_vdpa_parsing(vmm/src/config.rs),验证path=/dev/vhost-vdpa与path=/dev/vhost-vdpa,num_queues=2,id=my_vdpa两种写法的解析结果。
值得注意的是,VdpaConfig还实现了ApplyLandlocktrait(vmm/src/vm_config.rs),在启用 Landlock 沙箱时会对path指向的设备节点添加"rw"(读写)访问规则,即 vDPA 设备节点是 VMM 沙箱中需要显式放行的资源。
参数详解
path
vDPA 设备的路径,通常是/dev/vhost-vdpa-X。
- 必填。
- 类型为字符串。
示例
--vdpa path=/dev/vhost-vdpa-0num_queues
vDPA 设备支持的 virtqueue 数量。该值需要与设备实际能力匹配,使用vdpa dev config show之类的内核工具可以查询设备支持的队列数。
- 可选。
- 类型为无符号整数,默认值为
1。
示例
--vdpa path=/dev/vhost-vdpa-0,num_queues=2id
vDPA 设备的标识符。id的校验在配置校验阶段执行(vmm/src/config.rs):若提供则必须在整个虚拟机范围内唯一,且当启用 IOMMU 时(iommu=on)会同步使 VM 全局 IOMMU 生效。
- 可选。若提供,必须在整个虚拟机内唯一。
- 类型为字符串。
示例
--vdpa path=/dev/vhost-vdpa-0,id=vdpa0pci_segment
vDPA 设备应挂载到的 PCI segment 号。从源码看,pci_segment通过u16类型解析,默认值为0;校验时会与 VM 平台配置中的num_pci_segments比较,超出范围会报InvalidPciSegment错误(vmm/src/config.rs)。
- 可选。
- 类型为 16 位无符号整数,默认值为
0。
示例
--vdpa path=/dev/vhost-vdpa-0,pci_segment=1pci_device_id
分配给 vDPA 设备在其 PCI 总线上的设备 ID(slot 号)。pci_device_id以u8解析(vmm/src/config.rs),不指定时由系统自动分配。取值范围遵循 Cloud Hypervisor 的 PCI 分配规则:在 PCI segment 0 上为 1-31,在其他 PCI segment 上为 0-31。
- 可选。若未指定,将自动分配一个设备 ID。
- 类型为无符号整数,取值范围:PCI segment 0 上为 1-31,其余 PCI segment 上为 0-31。
示例
--vdpa path=/dev/vhost-vdpa-0,pci_device_id=5iommu
是否启用 IOMMU(通过PciDeviceCommonConfig::OPTIONS_IOMMU中的iommu=on|off开关控制)。从源码可以确认两处关键行为:
- 校验阶段(vmm/src/config.rs):任一 vDPA 设备开启 IOMMU 后,会将该选项向上传播,使整个 VM 的 IOMMU 生效;
- 校验规则(vmm/src/config.rs):若目标 PCI segment 被配置为
iommu_segments,则该设备必须开启iommu=on,否则报OnIommuSegment错误。
示例
--vdpa path=/dev/vhost-vdpa-0,iommu=on实战:使用 vDPA block 模拟器验证 vDPA 设备
当宿主机没有真实 vDPA 硬件时,可以利用内核 vDPA 框架自带的模拟器进行验证。该模拟器同时提供virtio-block与virtio-net两种实现,非常适合在无硬件环境下测试 vDPA 的完整链路。Cloud Hypervisor 的设备创建路径(make_vdpa_device,见 vmm/src/device_manager.rs)对真实设备与模拟器设备一视同仁,因此下述步骤对两者均适用。
第 1 步:加载内核模块
前提是宿主内核包含相应模块,全部加载:
sudo modprobe vdpa sudo modprobe vhost_vdpa sudo modprobe vdpa_sim sudo modprobe vdpa_sim_blk第 2 步:创建 vDPA 设备
需要宿主机安装iproute2/vdpa工具。创建virtio-blockvDPA 设备并调整设备节点权限,使其归属于当前用户:
sudo vdpa dev add name vdpa-blk1 mgmtdev vdpasim_blk sudo chown $USER:$USER /dev/vhost-vdpa-0 sudo chmod 660 /dev/vhost-vdpa-0第 3 步:放开内存锁限制
增大最大锁定内存,确保建立 IOMMU 映射能够成功(vDPA 的 DMA 映射需要锁定内存以固定物理页):
ulimit -l unlimited第 4 步:启动 Cloud Hypervisor
以一块 raw 镜像 + vDPA block 设备的完整配置为例:
cloud-hypervisor \ --cpus boot=1 \ --memory size=1G,hugepages=on \ --disk path=focal-server-cloudimg-amd64.raw,image_type=raw \ --kernel vmlinux \ --cmdline "root=/dev/vda1 console=hvc0" \ --vdpa path=/dev/vhost-vdpa-0,num_queues=1第 5 步:在 Guest 内验证
启动后,由 vDPA 模拟器支撑的virtio-block设备在 Guest 中呈现为/dev/vdb。通过lsblk可看到它与系统盘vda并列:
cloud@cloud:~$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT nullb0 252:0 0 250G 0 disk vda 254:0 0 2.2G 0 disk ├─vda1 254:1 0 2.1G 0 part / ├─vda14 254:14 0 4M 0 part └─vda15 254:15 0 106M 0 part /boot/efi vdb 254:16 0 128M 0 disk此后即可像使用普通 virtio-blk 设备一样对/dev/vdb进行分区、格式化与挂载操作。
常见问题与排障要点
- 设备节点缺失:
path指向的/dev/vhost-vdpa-X不存在,通常是 vhost-vdpa 模块未加载或vdpa dev add未执行成功。确认ls /dev/vhost-vdpa*有输出。 - 权限不足:VMM 进程需要对设备节点具备读写权限,否则无法打开设备。上述示例中通过
chown/chmod显式放开;若运行在 Landlock 沙箱下,VdpaConfig的apply_landlock实现已自动为设备节点添加rw规则。 - IOMMU 相关报错:若设备所在 PCI segment 属于
iommu_segments却未配置iommu=on,校验阶段即报OnIommuSegment;反过来,后端若不支持VIRTIO_F_ACCESS_PLATFORM,virtio-devices/src/vdpa.rs会以Missing VIRTIO_F_ACCESS_PLATFORM feature拒绝创建设备。 - IOVA 范围异常:内核侧返回非法 IOVA 范围时,驱动层会报告
InvalidIovaRange。可尝试重启模拟器设备或改用其他管理设备(mgmtdev)重建。 - 迁移相关:vDPA 的迁移能力依赖
VHOST_BACKEND_F_SUSPEND这类后端特性,实际可用性以宿主机内核与设备固件支持为准。
小结
vDPA 为 Cloud Hypervisor 提供了一条兼顾"接近裸机性能"与"易迁移性"的设备透传路径:数据面通过 virtqueue 的 DMA 直通获得性能,控制面借助内核 vhost-vdpa 框架保持通用。本文覆盖了从原理、VdpaConfig全参数语义到基于vdpa_sim_blk模拟器的完整验证流程;进一步阅读可参考内核 vDPA 框架的官方文档,以及在仓库中查看 config.rs 的参数解析与校验、vm_config.rs 的结构定义 与 virtio-devices/vdpa.rs 的设备驱动实现,从而掌握 vDPA 在 Cloud Hypervisor 内部从配置到激活的完整链路。
【免费下载链接】cloud-hypervisorA Virtual Machine Monitor for modern Cloud workloads. Features include CPU, memory and device hotplug, support for running Windows and Linux guests, device offload with vhost-user and a minimal compact footprint. Written in Rust with a strong focus on security.项目地址: https://gitcode.com/GitHub_Trending/cl/cloud-hypervisor
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考