当前位置: 首页 > news >正文

[virtio](八):vhost-user 与独立用户态数据面

第七篇讨论了 virtio-net 和 vhost-net。本篇继续看 vhost-user:如果 virtio 数据面不在 QEMU,也不在 host kernel,而是在另一个用户态进程里,QEMU 如何把 guest memory、virtqueue 和 eventfd 交给它?

1. vhost-user 解决什么问题

vhost-kernel 把数据面下沉到 host kernel。

vhost-user 则把数据面交给一个独立的用户态 backend process。

典型场景是高性能网络,例如 DPDK 相关后端。

模型如下:

QEMU process | | vhost-user protocol over Unix socket v vhost-user backend process | v high-performance packet processing

它的目标是:

  • 让数据面独立演进
  • 让 backend 使用 DPDK/SPDK 等用户态高性能框架
  • 避免 QEMU 主循环处理高频数据包
  • 在 QEMU 之外部署专门的 I/O backend

代价是系统结构更复杂。

2. vhost-user 与 vhost-kernel 的区别

vhost-kernel:

QEMU | | ioctl to kernel vhost device v host kernel vhost backend

vhost-user:

QEMU | | Unix socket messages v user-space backend process

二者都接管 virtqueue 数据面。

区别在于 backend 运行位置不同。

vhost-kernel 适合利用内核网络栈和 tap。

vhost-user 适合独立用户态包处理、DPDK、用户态存储后端或定制数据面。

3. QEMU 仍然是控制面

即使使用 vhost-user,QEMU 仍然负责 virtio 设备控制面。

包括:

  • 创建设备
  • 暴露 transport
  • feature negotiation
  • device status
  • queue setup
  • reset
  • migration coordination
  • 管理接口
  • 与 backend 建立连接

vhost-user backend 处理的是数据面。

结构是:

QEMU control plane | | vhost-user protocol v backend data plane

这和 vhost-net 的思想一致,只是 backend 从 kernel 变成了另一个用户态进程。

4. vhost-user 协议传什么

QEMU 和 vhost-user backend 通过 Unix socket 交换控制消息。

常见信息包括:

  • feature bits
  • protocol feature bits
  • guest memory regions
  • vring addresses
  • vring size
  • kick eventfd
  • call eventfd
  • queue enable state
  • backend configuration
  • migration/inflight state

其中 guest memory region 和 vring 信息最关键。

backend 要直接处理 guest virtqueue,就必须知道:

guest physical address 如何映射到 backend 可访问的 host virtual address descriptor table 在哪里 avail ring 在哪里 used ring 在哪里 kick/call eventfd 是哪些

5. guest memory 如何共享给 backend

vhost-user backend 是独立进程。

它不能天然访问 QEMU 进程中的 guest RAM。

因此 QEMU 需要通过协议把 guest memory region 描述和文件描述符传给 backend。

常见方式是基于共享内存 fd。

抽象模型:

QEMU owns guest RAM mappings | | send memory region metadata + fd v vhost-user backend maps same memory | v backend can access virtqueue and packet buffers

这一步非常敏感。

如果 memory table 错误,backend 解析 descriptor 时就无法正确访问 guest buffer。

6. vring 如何交给 backend

Guest 配置 virtqueue 后,QEMU 知道 vring 的地址和大小。

QEMU 会通过 vhost-user 协议告诉 backend:

queue index queue size descriptor table address avail ring address used ring address

backend 拿到这些信息后,就可以像 QEMU 或 vhost-kernel 一样解析 descriptor chain。

路径是:

Guest writes descriptors | v virtqueue in guest RAM | v vhost-user backend maps memory and reads vring | v backend processes I/O

QEMU 不再逐个解析高频 descriptor。

7. kick 和 call eventfd

vhost-user backend 还需要通知机制。

QEMU 会把 eventfd 传给 backend。

kick fd: guest -> backend,有新 descriptor call fd: backend -> guest,有 completion

完整路径:

Guest updates avail ring | | kick eventfd v vhost-user backend wakes | v backend processes descriptors | | call eventfd v KVM injects interrupt / QEMU handles notify | v Guest sees completion

如果配置了 irqfd,completion 可以更快进入 guest interrupt injection 路径。

8. vhost-user-net 的典型场景

vhost-user-net 常见于 DPDK 场景。

结构类似:

Guest virtio-net driver | v virtqueue in guest RAM | v vhost-user socket | v DPDK backend process | v physical NIC / userspace switch

数据包可以在用户态网络栈中高速处理,减少传统内核网络栈和 QEMU 主循环开销。

常见后端可以是:

  • OVS-DPDK
  • VPP
  • 自定义 DPDK 程序
  • 用户态虚拟交换机

9. vhost-user 的复杂度

vhost-user 的灵活性来自进程解耦。

但复杂度也来自进程解耦。

需要处理的问题包括:

  • backend 进程生命周期
  • socket 重连
  • feature 兼容
  • memory region 更新
  • queue 启停顺序
  • migration 协调
  • backend 崩溃恢复
  • 安全隔离
  • NUMA 和 hugepage placement

如果 backend 崩溃,QEMU 需要决定 VM 如何表现。

如果 memory mapping 不一致,backend 可能读错 guest buffer。

如果 migration 时 backend 状态没保存,target 恢复后可能丢包或 queue 卡住。

10. vhost-user 与迁移

vhost-user 迁移比基础 QEMU device model 更复杂。

因为设备状态分散在 QEMU 和 backend 中。

迁移时需要:

pause or quiesce backend data plane | v collect virtqueue state and inflight descriptors | v serialize QEMU virtio state | v coordinate backend state | v restore on target | v reconnect or start target backend | v resume queues

如果存在 in-flight packet 或 request,需要确保它不会丢失或重复完成。

这也是 vhost-user protocol feature 和 backend migration 能力重要的原因。

11. vhost-user 的安全边界

vhost-user backend 能访问 guest memory 中的 virtqueue 和 data buffer。

这意味着它处在敏感边界上。

安全设计需要考虑:

  • backend 进程权限
  • shared memory 范围
  • fd 传递
  • sandboxing
  • backend 输入验证
  • descriptor 合法性检查
  • guest 和 backend 之间的隔离

vhost-user 并不因为在用户态就天然安全。

它获得了高性能访问能力,也承担了正确解析 guest 提供数据结构的责任。

12. 源码阅读入口

本篇可以看:

  • hw/virtio/vhost-user.c
  • hw/virtio/vhost.c
  • include/hw/virtio/vhost.h
  • include/hw/virtio/vhost-user.h
  • hw/net/vhost_net.c
  • net/vhost-user.c
  • docs/interop/vhost-user.rst

阅读问题:

  • QEMU 如何连接 vhost-user socket?
  • memory region 如何发送给 backend?
  • vring address 如何设置?
  • kick/call eventfd 如何传递?
  • backend feature 如何协商?
  • backend 启停和 reset 如何处理?
  • migration 相关状态如何协调?

13. 本篇小结

vhost-user 把 virtio 数据面交给独立用户态 backend。

QEMU 通过 Unix socket 把 guest memory、vring、eventfd、feature 和 queue 状态传递给 backend。

backend 直接处理 guest virtqueue,QEMU 保留控制面和迁移编排。

可以把本篇压缩成一句话:

vhost-user 用进程边界换取数据面灵活性,让 virtio backend 可以独立优化,但也把 memory sharing、queue state、迁移和故障恢复变成必须认真处理的系统问题。

14. 下一篇预告:virtio 设备迁移状态

下一篇讨论 migration。

会回答:

  • virtio 迁移为什么不只是复制 guest RAM?
  • queue index、feature、config 和 pending interrupt 如何保存?
  • in-flight request 如何处理?
  • vhost backend 如何配合迁移?

下一篇的问题可以写成:

一台 VM 迁移到 target host 后,guest driver 为什么还能相信 virtio 设备只是暂停了一下?

http://www.jsqmd.com/news/1333843/

相关文章:

  • Qt开发者实战指南:从核心概念到项目部署的完整路径
  • 基于OpenClaw与DeepSeek打造智能QQ群助教:从零部署到技能开发实战
  • AI学机器学习避坑手册(2024最新版):覆盖Scikit-learn/TensorFlow/PyTorch三大生态,含17个真实项目踩坑复盘
  • 磷化铟光芯片:中国光通信产业的核心瓶颈与突破路径
  • Bifrost三星固件管理工具:终极免费跨平台解决方案
  • 国产CIM软件的实力选择——上扬软件品牌深度解读
  • 快速解决ViGEmBus虚拟游戏控制器安装与使用问题的完整指南
  • Vue项目打包体积优化实战:从3.2MB到380KB的性能瘦身指南
  • OpenClaw:构建AI智能体执行层,让大模型从聊天走向自动化
  • 赛车模型收藏指南:从Spark特注版选购到真伪鉴别与保养
  • 3大核心功能解析:KaTrain围棋AI训练平台如何重塑棋力提升体验
  • OpenClaw 2026:开源AI智能体平台部署与核心功能实战指南
  • WorkshopDL深度解析:如何用一款工具突破Steam创意工坊的平台壁垒
  • 2026 沈阳少儿编程怎么选?机构盘点、赛道区分、避坑干货一次性讲透
  • 解决Shotgun常见问题:静态文件服务与兼容性处理技巧
  • 从入门到精通:random_c2_profile变量系统(variables.py)完全指南
  • 质谱分析核心概念:精确质量、单同位素质量与质荷比解析
  • STM32与DHT11温湿度检测系统:从单总线协议到PCB设计的全流程实践
  • 楚雄市2026.8家里房子漏水怎么办?市面上多种方案可选择,哪种最适合自己?专业防水公司免费上门为您评估,家里漏水不再愁 - 超人防水
  • 数据同步如何保证不重、不丢、不错?一文讲清全量、增量、校验和异常处理
  • 告别手动敲哈希!Git Commit --fixup的终结者来了,你的提交历史该“自动整理”了
  • 老旧小区改造集中采暖系统选什么牌子靠谱?:【芬尼】旧改** - 17728098551
  • Exo用户自定义调度操作:打造专属优化策略
  • 提升Ruby开发效率:Shotgun高级功能与性能优化策略
  • PCL点云库从入门到精通:环境配置、核心算法与项目实战全指南
  • 突破尼泊尔语语音识别瓶颈:Wav2Vec2-Large-XLSR-53-Nepali核心技术解析
  • Firmament Autopilot嵌入式系统入门:FMT-Firmware核心功能与架构解析
  • 戴森球计划工厂蓝图库:3000+专业工厂设计方案终极指南
  • BLE传感器电路设计全解析:从芯片选型到低功耗优化实战
  • UE5 C++开发:为何必须用int32替代int?类型选择决定项目稳定性