深入分析Linux虚拟化KVM-Qemu之ioeventfd与irqfd

news2025/1/12 8:37:13

说明:

  1. KVM版本:5.9.1

  2. QEMU版本:5.0.0

  3. 工具:Source Insight 3.5, Visio

1. 概述

  • 图中的各个模块,只剩下通知机制没讲了,本文来一篇终结者;

Guest与KVM及Qemu之间的通知机制,如下图:

  • irqfd:提供一种机制,可以通过文件描述fd来向Guest注入中断,路径为紫色线条所示;

  • ioeventfd:提供一种机制,可以通过文件描述符fd来接收Guest的信号,路径为红色线条所示;

  • eventfd和irqfd这两种机制,都是基于eventfd来实现的;

本文会先介绍eventfd机制,然后再分别从Qemu/KVM来介绍ioeventfd和irqfd,开始吧。

2. eventfd

说来很巧,我曾经在工作中实现过一个类似eventfd机制的内核模块,用于多线程之间的轻量级通知,算是重复造轮子了。

eventfd的机制比较简单,大体框架如下图:

  • 内核中创建了一个struct eventfd_ctx结构体,该结构体中维护一个count计数,以及一个等待队列头;

  • 线程/进程在读eventfd时,如果count值等于0时,将当前任务添加到等待队列中,并进行调度,让出CPU。读过程count值会进行减操作;

  • 线程/进程在写eventfd时,如果count值超过最大值时,会将当前任务添加到等待队列中(特殊情况),写过程count值会进行加操作,并唤醒在等待队列上的任务;

  • 内核的其他模块也可以通过eventfd_signal接口,将count值加操作,并唤醒在等待队列上的任务;

代码实现如下图:

  • eventfd机制对用户层提供的系统调用接口包括eventfd(),write(),read(),select/poll等;

  • 通过eventfd来创建文件描述符,从代码中可以看出,该接口的实现为do_eventfd,完成的工作包括:

1)在内核中分配struct eventfd_ctx结构体来维护上下文;

2)初始化等待队列头用于存放睡眠等待的任务;

3)分配未使用的文件描述符fd,创建file实例(该实例会绑定操作函数集),将文件描述符fd与file实例建立连接等;

最终系统调用read/write时,便会分别调用到eventfd_read/eventfd_write函数:

  • eventfd_read:如果count值为0,将自身添加到等待队列中,设置任务的状态后调用schedule让出CPU,等待被唤醒。读操作中会对count值进行减操作,最后再判断等待队列中是否有任务,有则进行唤醒;

  • eventfd_write:判断count值在增加ucnt后是否会越界,越界则将自身添加到等待队列中,设置任务的状态后调用schedule让出CPU,等待被唤醒。写操作会对count值进行加操作,最后再判断等待队列中是否有任务,有则进行唤醒;

  • 此外,还有eventfd_signal接口,比较简单,完成的工作就是对count值进行加操作,并唤醒等待任务;

基石讲完了,我们来看看基于之上的ioeventfd和irqfd。

 资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linux内核源码内存调优文件系统进程管理设备驱动/网络协议栈

3. ioeventfd

3.1 Qemu侧

以PCI设备为例:

  • Qemu中模拟PCI设备时,在初始化过程中会调用memory_region_init_io来进行IO内存空间初始化,这个过程中会绑定内存区域的回调函数集,当Guest OS访问这个IO区域时,可能触发这些回调函数的调用;

  • Guest OS中的Virtio驱动配置完成后会将状态位置上VIRTIO_CONFIG_S_DRIVER_OK,此时Qemu中的操作函数调用virtio_pci_common_write,并按图中的调用流逐级往下;

  • event_notifier_init:完成eventfd的创建工作,它实际上就是调用系统调用eventfd()的接口,得到对应的文件描述符;

  • memory_region_add_eventfd:为内存区域添加eventfd,将eventfd和对应的内存区域关联起来;

看一下memory_region_add_eventfd的流程:

  • 内存区域MemoryRegion中的ioeventfds成员按照地址从小到大排序,memory_region_add_eventfd函数会选择合适的位置将ioeventfds插入,并提交更新;

  • 提交更新过程中最终触发回调函数kvm_mem_ioeventfd_add的执行,这个函数指针的初始化是在Qemu进行kvm_init时,针对不同类型的内存区域注册了对应的memory_listener用于监听变化;

  • kvm_vm_ioctl:向KVM注册ioeventfd;

Qemu中完成了初始化后,任务就转移到了KVM中。

3.2 KVM侧

KVM中的ioeventfd注册如下:

  • KVM中注册ioeventfd的核心函数为kvm_assign_ioeventfd_idx,该函数中主要工作包括:

1)根据用户空间传递过来的fd获取到内核中对应的struct eventfd_ctx结构体上下文;

2)使用ioeventfd_ops操作函数集来初始化IO设备操作;

3)向KVM注册IO总线,比如KVM_MMIO_BUS,注册了一段IO地址区域,当操作这段区域的时候出发对应的操作函数回调;

  • 当Guest OS中进行IO操作时,触发VM异常退出,KVM进行捕获处理,最终调用注册的ioevnetfd_write,在该函数中调用eventfd_signal唤醒阻塞在eventfd上的任务,Qemu和KVM完成了闭环;

总体效果如下图:

4. irqfd

Qemu和KVM中的流程如下图:

  • Qemu中通过kvm_irqchip_assign_irqfd向KVM申请注册irqfd;

  • 在KVM中,内核通过维护struct kvm_kernel_irqfd结构体来管理整个irqfd的流程;

  • kvm_irqfd_assign:

1)分配struct kvm_kernel_irqfd结构体,并进行各个字段的初始化;

2)初始化工作队列任务,设置成irqfd_inject,用于向Guest OS注入虚拟中断;

3)初始化等待队列的唤醒函数,设置成irqfd_wakeup,当任务被唤醒时执行,在该函数中会去调度工作任务irqfd_inject;

4)初始化pll_table pt字段的处理函数,设置成irqfd_ptable_queue_proc,该函数实际是调用add_wait_queue将任务添加至eventfd的等待队列中,这个过程是在vfs_poll中完成的;

  • 当Qemu通过irqfd机制发送信号时,将唤醒睡眠在eventfd上的任务,唤醒后执行irqfd_wakeup函数,在该函数中调度任务,调用irqfd_inject来注入中断;

总体效果如下图:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/379688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

wordpress从宝塔升级到docker

15还是16年的时候买的阿里云和腾讯云最低配的1核1G。腾讯云和阿里云后来都涨价了,退了涨价多的那个腾讯云,阿里云一直续费到现在,wordpress这个最早的时候是用军哥的lnmp的一键包搭建的,后来改成用了带UI的宝塔,宝塔用…

4.文件管理

文章目录1、初识文件管理1.1、回顾1.2、文件的属性1.3、无结构文件/有结构文件1.4、文件之间应该怎样组织起来?1.5、操作系统应该向上提供哪些功能?1.6、从上往下看,文件应如何存放在外存?1.7、其他需要由操作系统实现的文件管理功…

分页与分段

前面我们分析了虚拟地址和物理地址 我们这里进行一个简单的分析 这个是程序运行时的地址映射 那么这些碎片,我们现在的操作系统究竟如何处理呢? 我们再引入一个实际问题 我们如何把右边的进程p塞入左边的内存空间里面 有一种方法将p5kill掉&#xff…

Python - SQL入门和实战

数据来源 01 SQL前言 无处不在的SQL 后续学习的铺垫 学到什么程度 黑马程序员MySQL知识精讲mysql实战案例_零基础mysql数据库入门到高级全套教程_哔哩哔哩_bilibili 总结 02 数据库介绍 无处不在的数据库 数据库如何存储数据 数据库管理系统(数据库软件&#xf…

七、标签传播与节点分类【CS224W】(Datawhale组队学习)

开源内容:https://github.com/TommyZihao/zihao_course/tree/main/CS224W 子豪兄B 站视频:https://space.bilibili.com/1900783/channel/collectiondetail?sid915098 斯坦福官方课程主页:https://web.stanford.edu/class/cs224w 文章目录半…

或许你想要的画图工具在这里

之前文章发布后,有小伙伴问下面的画怎么画的(偷偷告诉你,其实我是用铅笔水彩笔画的),哈哈,开玩笑了。其实这些图都是用Excalidraw 画出来的。 我们平常不管是工作中,还是在日常写文章&#x…

pdf压缩文件大小的方法是什么?word文件怎么批量转换成pdf格式?

大家在存储文件时,通常会遇到一些较大的文件,这时需要对其进行压缩处理。下面介绍一下如何压缩PDF文件大小以及批量转换Word文件为PDF格式。pdf压缩文件大小的方法是什么?1.打开小圆象PDF转换器,选择“PDF压缩”功能。2.在“PDF压缩”界面中…

二、CSS

一、CSSHTML的结合方式 1、第一种&#xff1a;在标签的style属性上设置"key:value value;"&#xff0c;修改标签样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title>…

8位单片机(51 STC8)C语言处理32位unsigned long型数据之计算出错

一、问题描述 入门51没多久后就主攻32了&#xff0c;最近又搞起51&#xff0c;移植一个软定时器代码到STC8上&#xff0c;结果出现了奇怪的问题&#xff0c;而这种问题在各种32位单片机上都是不曾有的。 有如下代码&#xff0c;实现了软定时器。使用内部IRC&#xff0c;22.1184…

LabVIEW与Web通讯

LabVIEW与Web通讯Web客户端可通过LabVIEWWeb服务与远程LabVIEW应用程序交换数据。Web服务由运行在服务器上的VI和其他文件组成&#xff0c;这些VI对应于客户端发出的HTTP请求。LabVIEWWeb服务仅在LabVIEW完整版开发系统和LabVIEW专业版开发系统中可用。Web服务用于下列情况&…

服务器、存储、数据保护……又把奖拿了个遍

新一代高端存储      新一代中端存储      新一代入门级存储      新的数据保护产品线      新一代服务器和边缘服务器新品      … …      戴尔科技集团      在过去一年      继续保持强劲研发创新势头      不仅在硬件层面持续升级  …

NXP iMX8系列处理器Pin Multiplexing定义说明

By Toradex秦海1). 简介为了提高处理器的设计灵活性和可用性&#xff0c;NXP的所有i.MX系列处理器都配备了基于 IOMUX Controller (IOMUXC)和IOMUX来使能Pin Mux功能&#xff0c;使得一个特定的IO管脚可以选择不同的可能多达8种的功能定义模块(ALT0, ALT1, ALT2, ALT3...)&…

YOLOv5全面解析教程⑤:计算mAP用到的Numpy函数详解

作者 | Fengwen、BBuf 本文主要介绍在One-YOLOv5项目中计算mAP用到的一些numpy操作&#xff0c;这些numpy操作使用在utils/metrics.py中。本文是《YOLOv5全面解析教程④&#xff1a;目标检测模型精确度评估》的补充&#xff0c;希望能帮助到小伙伴们。 欢迎Star、试用One-YOLOv…

openpnp - configure - 主次基准点矫正

文章目录openpnp - configure - 主次基准点矫正概述备注ENDopenpnp - configure - 主次基准点矫正 概述 查找问题, 视觉里程碑只剩下4个问题了. 先看下设备上的主校准点, 我设备上的主校准点在设备前部的一个铝合金块上, 一块只带一个mark点的小PCB, 两边用螺丝拧住了.比PCB…

(五十四)大白话索引的页存储物理结构,是如何用B+树来实现的?.md

上一次我们给大家说了主键索引的目录结构&#xff0c;只要在一个主键索引里包含每个数据页跟他最小主键值&#xff0c;就可以组成一个索引目录&#xff0c;然后后续你查询主键值&#xff0c;就可以在目录里二分查找直接定位到那条数据所属的数据页&#xff0c;接着到数据页里二…

腾讯云轻量应用服务器配置表汇总(2核2G/2核4G/4核8G/8核16G)

轻量应用服务器&#xff08;TencentCloud Lighthouse&#xff09;是新一代开箱即用、面向轻量应用场景的云服务器产品&#xff0c;助力中小企业和开发者便捷高效的在云端构建网站、Web应用、小程序/小游戏、APP、电商应用、云盘/图床和开发测试环境&#xff0c;相比普通云服务器…

我的 System Verilog 学习记录(7)

引言 本文简单介绍 SystemVerilog 语言的 testbench 组件间通信和数据交互。 前文链接&#xff1a; 我的 System Verilog 学习记录&#xff08;1&#xff09; 我的 System Verilog 学习记录&#xff08;2&#xff09; 我的 System Verilog 学习记录&#xff08;3&#xff…

使用msvc命令行或msbuild编译dx3程序

从这里下载&#xff1a;https://github.com/microsoft/DirectX-Graphics-Samples cl.exe /D "UNICODE" /D "_UNICODE" *.cpp /EHsc -I C:\Users\54930\Downloads\DirectX-Graphics-Samples-master\Samples\Desktop\D3D12nBodyGravity\src\WinPixEventRun…

为什么DNS安全很重要

几乎所有web流量都需要标准DNS查询&#xff0c;这为DNS攻击创造了机会&#xff0c;比如DNS劫持和中间人攻击。这些攻击可以将网站的入站流量重定向到网站的伪造副本&#xff0c;收集敏感用户信息&#xff0c;并使企业承担重大责任。目前防范DNS威胁的最普遍方法之一是采用DNSSE…

为什么地图可视化炙手可热?

我们在谈到数据可视化的时候&#xff0c;可能第一反应就是中间有一个地图样式的大屏图。但有没有想过&#xff0c;为什么大多数的可视化大屏中间都是一张地图的样子&#xff1f;这张地图样式的模块究竟是什么呢&#xff1f;它又是怎么做出来的&#xff1f; 其实这张地图样式的…