virtio简介(二) —— virtio-balloon guest侧驱动
一: 概要
在后端模拟出balloon设备后,gustos在启动时会扫描到此设备,遵循linux设备模型调用设备的初始化工作。Virtio-balloon属于 virtio体系,很多工作的细节需要再分析virtio的工作流程,本章暂且只分析balloon的行为,涉及virtio的部分插桩分析向后再补充分析。
balloon执行流程如下:
回到顶部
二:驱动创建
2.1 驱动注册
Linux设备驱动模型中,各驱动可以按总线类别进行划分,且每个总线类别下可以挂载“驱动”和“设备”两类对象。内核就维护了这样一张“总线”到“驱动和设备”的总表,每当一个新驱动加进内核时,内核会扫描该驱动所挂载总线上的所有设备,并通过比对驱动中的id_table字段和设备配置空间中的Device ID,如果相同则代表该驱动可以为该设备服务,那内核就会针对该设备调用总线的probe函数(如果总线没有probe函数,再调用驱动的probe函数)。
另外一种情况是往总线上插入一个新设备,内核同样会扫描总线上的所有驱动,看哪个驱动匹配该设备,如果匹配也对该设备调用总线的probe函数(如果总线没有probe函数,再调用驱动的probe函数)。
Linux内核中前端代码主要包括driver/virtio目录下相关文件及driver/virtio_balloon.c,最终生成的内核模块有virtio.ko,virtio_ring.ko,virtio_pci.ko和virtio_balloon.ko。
由于virtio-balloon-pci设备是virtio-pci设备,而virtio-pci设备又是pci设备,所以virtio-pci设备的驱动会注册到pci总线上面,因此,整个初始化过程如下:
(1)内核会首先找到virito-pci.ko这个驱动模块,并依次加载virtio.ko,virtio-ring.ko和virtio_pci.ko (virtio_pci.ko依赖前两个模块)执行其模块初始化函数,其中,virtio.ko模块会在系统中注册一种新的总线类型virtio总线,virtio_pci的初始化函数会调用其注册的virtio_pci_probe函数;
(2)virtio_pci_probe注册一个virtio设备(register_virtio_device);
(3)内核再次为这个virtio设备搜索驱动模块,最终找到virtio_balloon.ko并加载调用其模块初始化函数;
(4)virtio_balloon初始化函数在virtio总线上添加了virtio_balloon驱动并调用了总线的probe函数(总线的probe函数优先级高于总线上设备的probe函数)即virtio_dev_probe;
(5)virtio_dev_probe调用virtballoon_probe完成最后的初始化任务。
我们最终需要关注的是virtballoon_probe这个函数是怎么被调用到的,linux设备初始化开始到调用到virtballoon_probe的过程简化如下,仅供参考:
驱动可执行的动作包含在virtio_balloon_driver定义的结构体中。先来看下这个结构体的内容,文件位置driver/virtio/virtio_balloon.c。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
可以看到,注册的 driver中注册了feature属性,driver的名称和owner,驱动加载的probe卸载的remove,感知变化的config_changed,这三个函数做了主要的工作。 先来看下加载做了什么工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
|
可以看到,这里的主要工作有:
1. 通过init_waitqueue_head初始化了两个工作队列用来接收QEMU发来的notify
2. 通过init_vqs初始化了3个 virt_queue用来和qemu发送balloon进行inflate/deflate的page地址信息以及callback回调
3. 启动内核线程执行vballoon,执行balloon的具体操作
2.2 vballoon如何运作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
|
主要涉及到的处理:
1. 添加等待队列,等待config_change被唤醒,即QEMU有执行balloon操作
2. 计算需要申请或者释放的空间,即diff值
3. 如果需要申请或者释放空间,则调用fill_balloon或者leak_balloon进行操作
4. 更新balloon实际占用的空间,记录到actual变量中,并通知给QEMU
计算diff值的操作如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
2.3 balloon充气过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
基本流程可以总结为:从gust空间申请页面放入balloon的链表中,并做标记使该内存内核不可用,填充设备的pfn数组,然后通过ivq通知设备侧进行处理。
2.4 leak_balloon过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
leak_balloon的过程和fill_balloon刚好相反,它会释放存放在balloon的page链表中的page项归还给gust,同理,这部分 内存会被qemu从host申请回来留给gustos备用,此时host主机的可用内存就减少了。
回到顶部
三. balloon结合shrinker工作过程
virtio简介(二) —— virtio-balloon guest侧驱动相关推荐
- Linux中断子系统(二)中断控制器GIC驱动分析
Linux中断子系统(二)中断控制器GIC驱动分析 备注: 1. Kernel版本:5.4 2. 使用工具:Source Insight 4.0 3. 参考博客: Linux中断子系统(一 ...
- [Qt教程] 第22篇 数据库(二)编译MySQL数据库驱动
[Qt教程] 第22篇 数据库(二)编译MySQL数据库驱动 楼主 发表于 2013-5-13 21:28:02 | 查看: 1616| 回复: 12 编译MyQSL数据库驱动 版权声明 该文章原创 ...
- NSG44273低侧驱动IC
国硅(新洁能旗下子公司)NSG44273低侧驱动IC,单通道2A高速低侧栅极驱动电路,pin对pin直接替换IRS44273 NSG44273 4.5V~25V工作电压范围 2A/2A峰值灌电流/拉电 ...
- NSG44272低侧驱动IC
国硅(新洁能旗下子公司)NSG44272低侧驱动IC,单通道2A高速低侧栅极驱动电路,pin对pin直接替换IRS44272 NSG44272 4.5V~25V工作电压范围 2A/2A峰值灌电流/拉电 ...
- PMOS和NMOS在开关应用中高侧和低侧驱动的对比
一说到开关,我们脑海中首先浮现的就是各式各样的机械开关,常见的有自锁开关.拨码开关.船型开关等等.区别于这类常见的机械开关,我们在电子电路中常用的还有各类半导体开关,例如三极管开关.使用三极管级联的达 ...
- MOS做电源开关的电路,NMOS、PMOS高侧低侧驱动大全解,电容浮栅自举电路,泄放电阻的作用,MOS选型参数分析
随着对器件的控制需求提升,越来越多的电源开关电路出现在设计中.这些设计的目的各有不同:有的需要快速开通与关断,有的需要低导通电阻+大电流,有的需要闲时0功耗.虽然应用场合不同,但做开关可是MOS的 ...
- 【正点原子MP157连载】第二十二章 新字符设备驱动实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7
1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...
- 二十一、SPI设备驱动及应用(二)
一.硬件电路 1.根据三星提供的exynos4412手册,我们选择我们要使用的SPI,如下图,我们选择SPI2 由上图可知,我们SPI2的四条线分别对应管脚: SPI_2_CLK -> Xi2s ...
- 二十、SPI设备驱动及应用(一)
先给出Linux SPI子系统的体系结构图: SPI子系统体系结构 下面开始分析SPI子系统. Linux中SPI子系统的初始化是从drivers/spi/spi.c文件中的spi_init函数开始的 ...
最新文章
- PackageManagerService详解
- cv::cuda::split 使用
- Mastercam X9中文版
- HOW TO ORDER LFT
- 喜欢linux的朋友加QQ群了170838394
- 诗歌rails 之自定义Helper模块
- Python中过滤序列内置函数filter()的详解(常用)
- 【Django】Django Debug Toolbar调试工具配置
- 【面向对象】聚合的四种语义
- 国外PHP学习网站书籍资料汇总
- P(A)P(B|A)=P(B)P(A|B)
- 华为上半年收入4540亿元;GitHub服务中断,已恢复​;Python 3.8.4发布|极客头条
- SQL语句的一些重要操作
- 使用Intent启动常用的应用与服务
- for循环的嵌套,for循环的穷举迭代
- gomod下导入模块的方法
- 洞察|2019年混合云发展:前景广阔 巨头混战 SD-WAN成重要推手
- LeetCode-两数之和(Java) 记录下刷题的第一天以及近期迷茫感受
- 04_使用域名访问后台管理系统(Nginx)
- LVGL v8.1.0 lv_table 内存泄漏问题