中移(苏州)软件技术有限公司面试问题与解答(4)—— virtio所创建的设备2

本文主要是介绍中移(苏州)软件技术有限公司面试问题与解答(4)—— virtio所创建的设备2,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

接前一篇文章:中移(苏州)软件技术有限公司面试问题与解答(4)—— virtio所创建的设备1

在上一篇文章中,对于面试所提出的问题“virtio会创建哪些设备?”,有了初步答案,即virtio后端设备分为两大类设备:virtio PCI控制设备和virtio设备。具体来说,就是virtio-pci设备和具体的virtio设备。本回对于细节进行讲解,在初步回答此面试问题的基础上,深入回答此问题。

virtio设备的初始化

virtio设备首先需要创建一个PCI设备,叫作 virtio PCI代理设备(就是上边的virtio PCI控制设备),这个代理设备挂到了PCI总线上;接着,virtio代理设备再创建一条virtio总线,这样virtio设备就可以挂到这条总线上了。

首先来看virtio PCI代理设备类型的定义,在hw/virtio/virtio-pci.c中,如下:

static const TypeInfo virtio_pci_info = {.name          = TYPE_VIRTIO_PCI,.parent        = TYPE_PCI_DEVICE,.instance_size = sizeof(VirtIOPCIProxy),.class_init    = virtio_pci_class_init,.class_size    = sizeof(VirtioPCIClass),.abstract      = true,
};

其中:

  • TYPE_VIRTIO_PCI

TYPE_VIRTIO_PCI的定义在include/hw/virtio/virtio-pci.h中,如下:

#define TYPE_VIRTIO_PCI "virtio-pci"
OBJECT_DECLARE_TYPE(VirtIOPCIProxy, VirtioPCIClass, VIRTIO_PCI)
  • TYPE_PCI_DEVICE

TYPE_PCI_DEVICE的定义在include/hw/pci/pci_device.h中,如下:

#define TYPE_PCI_DEVICE "pci-device"
typedef struct PCIDeviceClass PCIDeviceClass;
DECLARE_OBJ_CHECKERS(PCIDevice, PCIDeviceClass,PCI_DEVICE, TYPE_PCI_DEVICE)
  • VirtIOPCIProxy

VirtIOPCIProxy结构的定义也在include/hw/virtio/virtio-pci.h中,如下:

struct VirtIOPCIProxy {PCIDevice pci_dev;MemoryRegion bar;union {struct {VirtIOPCIRegion common;VirtIOPCIRegion isr;VirtIOPCIRegion device;VirtIOPCIRegion notify;VirtIOPCIRegion notify_pio;};VirtIOPCIRegion regs[5];};MemoryRegion modern_bar;MemoryRegion io_bar;uint32_t legacy_io_bar_idx;uint32_t msix_bar_idx;uint32_t modern_io_bar_idx;uint32_t modern_mem_bar_idx;int config_cap;uint32_t flags;bool disable_modern;bool ignore_backend_features;OnOffAuto disable_legacy;/* Transitional device id */uint16_t trans_devid;uint32_t class_code;uint32_t nvectors;uint32_t dfselect;uint32_t gfselect;uint32_t guest_features[2];VirtIOPCIQueue vqs[VIRTIO_QUEUE_MAX];VirtIOIRQFD *vector_irqfd;int nvqs_with_notifiers;VirtioBusState bus;
};
  • VirtioPCIClass

VirtioPCIClass结构的定义也在include/hw/virtio/virtio-pci.h中,如下:

struct VirtioPCIClass {PCIDeviceClass parent_class;DeviceRealize parent_dc_realize;void (*realize)(VirtIOPCIProxy *vpci_dev, Error **errp);
};

再回顾一下virtio PCI代理设备类型的定义:

static const TypeInfo virtio_pci_info = {.name          = TYPE_VIRTIO_PCI,.parent        = TYPE_PCI_DEVICE,.instance_size = sizeof(VirtIOPCIProxy),.class_init    = virtio_pci_class_init,.class_size    = sizeof(VirtioPCIClass),.abstract      = true,
};

由定义可知,virtio PCI代理设备的父设备是一个PCI设备(.parent        = TYPE_PCI_DEVICE,);virtio PCI代理设备的类型为VirtioPCIClass(.class_size    = sizeof(VirtioPCIClass),);virtio PCI代理设备的实例为VirtIOPCIProxy(.instance_size = sizeof(VirtIOPCIProxy),),注意这是一个抽象设备,所以并不能创建其实例,只能由其子类去创建。

QEMU(源码)中定义了所有virtio设备的PCI代理设备,如virtio balloon PCI设备、virtio scsi PCI设备、virtio crypto PCI设备等。以virtio scsi PCI设备为例,其定义在hw/virtio/virtio-scsi-pci.c中,如下:

static const VirtioPCIDeviceTypeInfo virtio_scsi_pci_info = {.base_name              = TYPE_VIRTIO_SCSI_PCI,.generic_name           = "virtio-scsi-pci",.transitional_name      = "virtio-scsi-pci-transitional",.non_transitional_name  = "virtio-scsi-pci-non-transitional",.instance_size = sizeof(VirtIOSCSIPCI),.instance_init = virtio_scsi_pci_instance_init,.class_init    = virtio_scsi_pci_class_init,
};

virtio设备在系统的设备树中的位置如下图所示:

所有的virtio设备都有一个共同的父类TYPE_VIRTIO_DEVICE。仍以virtio balloon设备为例,virtio balloon设备的定义在hw/virtio/virtio-balloon.c中,如下:

static const TypeInfo virtio_balloon_info = {.name = TYPE_VIRTIO_BALLOON,.parent = TYPE_VIRTIO_DEVICE,.instance_size = sizeof(VirtIOBalloon),.instance_init = virtio_balloon_instance_init,.class_init = virtio_balloon_class_init,
};

其中:

  • TYPE_VIRTIO_BALLOON

TYPE_VIRTIO_BALLOON的定义在include/hw/virtio/virtio-balloon.h中,如下:

#define TYPE_VIRTIO_BALLOON "virtio-balloon-device"
OBJECT_DECLARE_SIMPLE_TYPE(VirtIOBalloon, VIRTIO_BALLOON)
  • TYPE_VIRTIO_DEVICE

TYPE_VIRTIO_DEVICE的定义在include/hw/virtio/virtio.h中,如下:

#define TYPE_VIRTIO_DEVICE "virtio-device"
OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE)
  • VirtIOBalloon

VirtIOBalloon结构的定义在中,如下:

struct VirtIOBalloon {VirtIODevice parent_obj;VirtQueue *ivq, *dvq, *svq, *free_page_vq, *reporting_vq;uint32_t free_page_hint_status;uint32_t num_pages;uint32_t actual;uint32_t free_page_hint_cmd_id;uint64_t stats[VIRTIO_BALLOON_S_NR];VirtQueueElement *stats_vq_elem;size_t stats_vq_offset;QEMUTimer *stats_timer;IOThread *iothread;QEMUBH *free_page_bh;/** Lock to synchronize threads to access the free page reporting related* fields (e.g. free_page_hint_status).*/QemuMutex free_page_lock;QemuCond  free_page_cond;/** Set to block iothread to continue reading free page hints as the VM is* stopped.*/bool block_iothread;NotifierWithReturn free_page_hint_notify;int64_t stats_last_update;int64_t stats_poll_interval;uint32_t host_features;bool qemu_4_0_config_size;uint32_t poison_val;
};

再来回顾一下virtio balloon设备的定义:

static const TypeInfo virtio_balloon_info = {.name = TYPE_VIRTIO_BALLOON,.parent = TYPE_VIRTIO_DEVICE,.instance_size = sizeof(VirtIOBalloon),.instance_init = virtio_balloon_instance_init,.class_init = virtio_balloon_class_init,
};

由定义可知,virtio balloon设备的实例对象为VirtIOBalloon。具体的virtio设备、virtio PCI代理设备以及virtio公共设备的关系如下图所示:

到此,就能够完全、完整地回答“virtio会创建哪些设备?”这一面试问题了:

virtio会创建两类设备:

  • virtio PCI控制设备(也可称作virtio PCI代理设备)

virtio PCI代理设备virtio-pci是一个抽象设备,并不能创建实例,只能由其子类去创建实例,如virtio balloon PCI设备virtio-balloon-pci-base、virtio scsi PCI设备virtio-scsi-pci-base、virtio crypto PCI设备virtio-crypto-pci等。

  • virtio设备

virtio 设备virtio-device是一个抽象设备,并不能创建实例,只能由其子类去创建实例,如virtio balloon设备virtio-balloon-device、virtio scsi设备virtio-scsi-device、virtio crypto设备virtio-crypto-device等。

这篇关于中移(苏州)软件技术有限公司面试问题与解答(4)—— virtio所创建的设备2的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/646236

相关文章

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

MySQL 设置AUTO_INCREMENT 无效的问题解决

《MySQL设置AUTO_INCREMENT无效的问题解决》本文主要介绍了MySQL设置AUTO_INCREMENT无效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录快速设置mysql的auto_increment参数一、修改 AUTO_INCREMENT 的值。

Java中实现线程的创建和启动的方法

《Java中实现线程的创建和启动的方法》在Java中,实现线程的创建和启动是两个不同但紧密相关的概念,理解为什么要启动线程(调用start()方法)而非直接调用run()方法,是掌握多线程编程的关键,... 目录1. 线程的生命周期2. start() vs run() 的本质区别3. 为什么必须通过 st

关于跨域无效的问题及解决(java后端方案)

《关于跨域无效的问题及解决(java后端方案)》:本文主要介绍关于跨域无效的问题及解决(java后端方案),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录通用后端跨域方法1、@CrossOrigin 注解2、springboot2.0 实现WebMvcConfig

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码

Java死锁问题解决方案及示例详解

《Java死锁问题解决方案及示例详解》死锁是指两个或多个线程因争夺资源而相互等待,导致所有线程都无法继续执行的一种状态,本文给大家详细介绍了Java死锁问题解决方案详解及实践样例,需要的朋友可以参考下... 目录1、简述死锁的四个必要条件:2、死锁示例代码3、如何检测死锁?3.1 使用 jstack3.2

解决JSONField、JsonProperty不生效的问题

《解决JSONField、JsonProperty不生效的问题》:本文主要介绍解决JSONField、JsonProperty不生效的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录jsONField、JsonProperty不生效javascript问题排查总结JSONField

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos