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

linux 之 virtio 子系统核心的数据结构

1、 virtio_bus结构

struct bus_type是基于总线驱动设备模型的虚拟总线,定义新的bus,就是填充该结构。virtio_bus定义在drivers/virtio/virtio.c中,具体如下,

注册:

补充注册的早不早:

virtio_bus以core_initcall的方式被注册,该方式注册的启动顺序优先级很高(作为对比,module_init最终对应的是device_initcall),在使用中要注意不同组件的启动顺序。

补充2:virtio_dev_match函数

virtio驱动的match涉及到virtio_device_id结构,在virtio_device结构中包含该结构;在virtio_driver中则是包含该驱动支持的virtio_device_id列表

具体的match流程如下,

可见virtio驱动的match函数先匹配device字段,后匹配vendor字段,二者都满足条件时match成功

补充3:从virtio_dev_match的流程可以看出,virtio_driver中的id_table必须以id->device = 0结尾,以便结束循环

2 virtio_device结构

struct virtio_device定义在include/linux/virtio.h中,具体如下,

2.1 struct virtio_device_id id

其中的device成员标识了当前virtio_device的用途,virt-net是其中的一种,

2.2 const struct virtio_config_ops *config

virtio_config_ops操作集中的函数主要与virtio_device的配置相关,主要有如下2类操作,

  • 实例化 / 反实例化virtqueue,其中要特别注意find_vqs函数,该函数用于实例化virtio_device所持有的virtqueue
  • . 获取 / 设置virtio_device的属性与状态,相关属性均在虚拟机虚拟出的PCI配置空间

2.3 struct list_head vqs

virtio_device持有的virtqueue链表,virtio-net中建立了2条virtqueue

2.4 u64 features

irtio_driver & virtio_device同时支持的通信特性,也就是前后端最终协商的通信特性

3 virtio_driver结构

struct virtio_driver定义在include/linux/virtio.h中,具体如下,

3.1 const struct virtio_device_id *id_table

对应virtio_device结构中的id成员,virtio_device中标识的是当前device的id属性;而virtio_driver中的id_table则是当前driver支持的所有id列表

3.2 const unsigned int *feature_table & unsigned int feature_table_size

feature列表包含了当前driver支持的所有virtio传输属性,feature_table_size则说明属性数组的元素个数

4 virtqueue结构

struct virtqueue定义在include/linux/virtio.h中,具体如下,

vdev 是引用了 virtio_device 的实例。

5 vring结构

struct vring 定义在include/uapi/linux/virtio_ring.h中,具体如下,

一定要结合一个后端驱动进行分析,可以对照rpmsg-lite分析

可以就分析rpmsg-lite对virtqueue的操作部分,不用上升到rpmsg协议的部分

说明1:vring的三个构成区域

  • Destcriptor Table:描述内存buffer,主要包括addr & len等信息
  • Avail Ring:用于前端驱动(Guest)通知后端驱动(Host)有可用的描述符

e.g. 前端驱动有一个报文需要发送,需要将其加入Avail Ring,之后通知后端驱动读取

  • Used Ring:用于后端驱动(Host)通知前端驱动(Guest)有可用的描述符,或者是后端驱动已将前端驱动提供的描述符使用完毕

e.g. 后端驱动有一个报文需要发送,需要将其加入Used Ring,之后通知前端驱动读取

可见avail & used的命名都是站在Host的角度进行的

说明2:vring的存储

vring结构只是用于描述vring在内存中的布局(因此包含的都是指针变量),实际用于通信的vring是存储在内存中

上文提到的vring的三个区域是在内存中连续存储的,而且是存储在Guest & Host共享的一片连续内存中

我们可以通过vring_init函数理解vring存储结构的布局

实际vring的内存布局如下图所示,

在计算used ring的起始地址时,在avail->ring[num]的地址之后又加了sizeof(__virtio16),也就是增加了2B,是为了容纳avail ring末尾的used_event,该机制详见下文(是一种控制中断触发频率的机制)

说明3:实际vring的大小

实际vring的大小可以通过vring_size函数获得

① 计算avail ring时加3,分别为flags、idx和used_event

② 计算used ring时加3,分别为flags、idx和avail_event

③ 计算过程中,包含了为满足对齐要求padding的空间

说明4:used_event与avail_event机制概述

这2个字段均与virtio设备的VIRTIO_RING_F_EVENT_IDX特性有关,由于virtio驱动触发对方中断将导致CPU反复进出虚拟机 & 宿主机模式,从而降低性能,因此需要控制触发中断频率的机制

① avail ring中的used_event

a. 由前端驱动(Geust)设置,标识希望后端驱动(Host)触发中断的阈值

b. 后端驱动(Host)在向Used Ring加入buffer后,检查Used Ring中的idx字段,只有达到阈值才触发中断

② used_ring中的avail_event

a. 由后端驱动(Host)设置,标识希望前端驱动(Guest)触发中断的阈值

b. 前端驱动(Guest)在向Avail Ring加入buffer后,检查Avail Ring的idx字段,只有达到阈值才触发中断

综上所属,vring结构的构成如下图所示,

6 vring_virtqueue结构

vring_virtqueue结构用于描述前端驱动(Guest)中的一条虚拟队列

总结:virtio_device / vring_virtqueue / virtqueue / vring结构之间的关系

http://www.dtcms.com/a/343023.html

相关文章:

  • DeepSeek R2难产:近期DeepSeek-V3.1 发布更新并开源,成功实现迈向 Agent 时代的第一步
  • 信息收集4----(收集网站指纹信息)
  • CSS 3D动画,围绕旋转动画Demo
  • 常见 Linux 网络命令梳理
  • AGV 技术落地场景解析:从制造业到仓储物流,看自动导引车的行业应用
  • 【Ruoyi解密-02.登录流程:】登录-找密码不抓瞎
  • 封装FTPSClient连接ftps服务器
  • 一个成熟的运维及售后岗位应掌握的知识体系详解
  • Linux动态库制作和使用
  • Manus AI 与多语言手写识别:技术、应用与未来
  • Nginx + Vue/React 前端 + API:防止路径混淆漏洞与跨域问题实战分享
  • [Mysql数据库] Mysql安全知识
  • Oracle ADG 切换方式详解:Switchover 与 Failover 操作指南
  • 〖领码方案〗前端 PageData 完整解决方案 第四版
  • 深度解析Structured Outputs:让AI输出严格遵循JSON Schema的结构化响应
  • 【日常学习】2025-8-21 了解些测试名词
  • 【GPT入门】第52课 openwebui安装与使用
  • Zynq中级开发七项必修课-第三课:S_AXI_GP0 主动访问 PS 地址空间
  • 通信算法之317:基于Xilinx FPGA平台的符号同步算法(接收序列与本地序列互相关-不共轭乘)
  • ODDR实现多bit单边沿采样数据转为多bit双沿采样数据
  • 前端-Vue笔记(核心语法)
  • linux内核 - 内存分配机制介绍
  • MySQL 8.4.6 LTS 安装教程 windows
  • 如何在mac玩windows游戏?3个工具推荐,不用换电脑!
  • MiniGPT-4
  • 在Excel和WPS表格中合并多个单元格这样最快
  • 第14章 结构和其他数据形式
  • 数据分类分级的关键难点以及应对之道
  • Go1.25的源码分析-src/runtime/runtime1.go(GMP)g
  • U盘安装 CentOS Stream 10 实战复盘:三大常见问题与解决方法