虚拟化 GPU 的性能瓶颈往往不在\”算得快不快\”,而在\”数据搬得多不多\”。如果 Guest 应用的每一帧、每一个纹理都要在 Guest 与 Host 之间拷贝一遍,再快的 GPU 也会被内存带宽拖垮。本章讲 virglrenderer 如何用 Blob 资源 + DMA-BUF 实现 Host–Guest 之间的零拷贝共享内存。
该机制是基于 Virtio 虚拟化的核心机制。要理解该机制,就要理解 Linux 的 mm 子系统和 drm 子系统的工作原理,因此是学习 mm/drm 的一个比较好的用例。想深度理解原理和实现的朋友们可参阅:
- Linux DRM 子系统实现与产品化案例剖析
- Linux 内存管理子系统的进化——从 MM 到 HMM
7.1 从\”传统资源\”到\”Blob 资源\”
第4章介绍过两类资源,这里从内存视角再看一次它们的本质区别:
- 传统资源(conventional resource):Guest 侧有一块内存(用 iovec 描述的 scatter-gather 页),Host 侧有一块对应的 GPU 资源。二者是两份内存,靠 transfer_3d 显式搬运(TRANSFER_TO_HOST / FROM_HOST)。语义清晰,但每次同步都要拷贝。
- Blob 资源:一块\”未定型的字节缓冲\”,可以被映射进 Guest 地址空间、导出为 fd、在 Host 与 Guest 之间共享同一份物理内存。这是零拷贝的基础。
Blob 资源由 VIRTIO_GPU_F_RESOURCE_BLOB 特性启用,virglrenderer 侧的创建接口:
struct virgl_renderer_resource_create_blob_args {
uint32_t res_handle;
uint32_t ctx_id;
uint32_t blob_mem; /* 内存归属:GUEST / HOST3D / HOST3D_GUEST */
uint32_t blob_flags; /* 用途:MAPPABLE / SHAREABLE / CROSS_DEVICE / … */
uint64_t blob_id;
uint64_t size;
const struct iovec *iovecs;
uint32_t num_iovs;
};
int virgl_renderer_resource_create_blob(
const struct virgl_renderer_resource_create_blob_args *args);
7.2 blob_mem:内存住在哪
blob_mem 决定这块内存的\”物理归属\”,是理解零拷贝路径的关键:
网硕互联帮助中心







评论前必须登录!
注册