189 8069 5689

如何进行virtio的分析-创新互联

本篇文章为大家展示了如何进行virtio的分析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

“只有客户发展了,才有我们的生存与发展!”这是创新互联的服务宗旨!把网站当作互联网产品,产品思维更注重全局思维、需求分析和迭代思维,在网站建设中就是为了建设一个不仅审美在线,而且实用性极高的网站。创新互联对网站设计、成都网站建设、网站制作、网站开发、网页设计、网站优化、网络推广、探索永无止境。

virtio


virtio是一个通用的io虚拟化框架,hypervisor通过他模拟出一系列的虚拟化设备,并使得这些设备在虚拟机内部通过api调用的方式变得可用。它为客户机提供了一个高效访问块设备的方法。它包含4个部分:前端驱动、后端驱动、vring及通信间统一的接口。与其他的模拟io方式对比,virtio减少了虚拟机的退出和数据拷贝,能够极大地提高IO性能。计算机中存在不同的总线标准,而virtio采用的是pci总线(当然也可以用其他总线来实现)。每一个virtio设备就是一个pci设备。

如何进行virtio的分析

virtio-blk的后端初始化


virtio-blk代码包保存在hw/virtio-pci.c和hw/virtio-blk.c中,通过如下函数对virtio_blk进行初始化。主要的初始化函数是virtio_blk_init_pci。这里定义了设备的信息。

static void virtio_blk_class_init(ObjectClass *klass, void *data) {     DeviceClass *dc = DEVICE_CLASS(klass);     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);     k->init = virtio_blk_init_pci;   //virtio-blk初始化函数     k->exit = virtio_blk_exit_pci;     k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;     //设备厂商号,所有的virtio设备都为0x1af4     k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;          //设备号     k->revision = VIRTIO_PCI_ABI_VERSION;  //virtio ABI版本号     k->class_id = PCI_CLASS_STORAGE_SCSI;     dc->reset = virtio_pci_reset;     dc->props = virtio_blk_properties;   //virtio-blk设备所支持的特征 }   static TypeInfo virtio_blk_info = {     .name          = "virtio-blk-pci",     .parent        = TYPE_PCI_DEVICE,     .instance_size = sizeof(VirtIOPCIProxy),     .class_init    = virtio_blk_class_init,       //virtio-blk设备类型初始化函数 };

virtio_blk后端数据结构如下

如何进行virtio的分析

如何进行virtio的分析

virtio-blk首先是一个pci设备,初始化主要分两个阶段:pci设备初始化和设备初始化

以下是它初始化的几个阶段:

  • PCI设备探测和初始化

虚拟机启动时,bios和系统会扫描pci总线,看看上面有没有挂载的pci设备。如果有,则会创建一个pci_dev结构。一个pci设备用一个pci_dev数据结构表示,创建之后会用pci设备配置空间信息来填充pci_dev,然后调用device_register来将其注册到pci总线上。PCI总线的match和probe函数根据pci_dev数据结构中的Vendor ID和Device ID将设备与注册在PCI总线上的驱动进行匹配,进而匹配到了所有virtio设备所共用的PCI驱动virtio_pci_driver。

static struct pci_device_id virtio_pci_id_table[] = {          { 0x1af4, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },          { 0 }, };   // PCI_ANY_ID表示匹配任何设备ID static struct pci_driver virtio_pci_driver = {          .name                  = "virtio-pci",      //驱动名称          .id_table         = virtio_pci_id_table,  //驱动所支持的设备ID信息          .probe                  = virtio_pci_probe,//探测函数(负责PCI设备初始化和进一步的virtio设备探测)          .remove               = virtio_pci_remove,//设备移除时的处理函数 #ifdef CONFIG_PM          .driver.pm  = &virtio_pci_pm_ops, //电源管理函数 #endif };
  • virtio设备的探测和初始化

virtio_pci_driver是该阶段的关键函数,具体流程如下

如何进行virtio的分析

如何进行virtio的分析

  1. 前端驱动读取io请求放入vring

  2. 前端通过notify通知机制通知后端驱动处理io

  3. notify操作使vcpu执行线程退出到qemu应用层,其从vring中获取客户机io请求信息,将请求线程放入aio线程池,然后vcpu线程的处理流程重新返回到客户机

  4. aio线程处理完成后,通知主线程,并向客户机注入中断说明其已完成io操作

  5. 客户机相应中断,并获取io请求结果和处理信息,接着继续向上层返回结果

客户机io请求流程


如何进行virtio的分析

1、读写操作通过系统调用进入到操作系统内核层,首先到达VFS层

2、VFS层继续向下层传递请求,如果页高速缓存命中,而文件又不是直接读写,则IO请求在页高速缓存得到处理

3、如果没有页高速缓存或者页高速缓存MISS,则进入到Mapping Layer(映射层),在这一层主要是根据文件系统信息,解决文件偏移量与块设备中的的逻辑块号的映射,并根据映射将请求下发到Generic Block Layer(通用块层)

4、在通用块层,IO读写请求由struct bio表示,通用块层继续将请求下发到IO Scheduler Layer(IO调度层)

5、在IO调度层,上层传递下来的bio将根据类型、以及逻辑块是否靠近等因素进行调度,最终形成一个req(struct request类型),req将被链接到设备的request_queue中

6、IO调度层继续将请求下发,请求到达了块设备驱动,块设备驱动从request_queue中取下一个个请求进行处理。

上述内容就是如何进行virtio的分析,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联行业资讯频道。

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


网站标题:如何进行virtio的分析-创新互联
标题链接:http://cdxtjz.com/article/iephi.html

其他资讯