virtio-mem

1、架构支持性

X86_64:已经支持
Arm: https://lore.kernel.org/all/20211130003328.201270-1-gshan@redhat.com/T/#u 相关patch已经提交到内核(审核通过,代码已合入)

2、Guest OS支持性

Linux已经支持
windows:https://ourwindowsman.wordpress.com/2020/11/03/virtio-mem-goes-to-windows/

3、Kernel

Linux guest 从内核版本5.8-rc开始支持virtio-mem

4、Qemu

Qemu从5.1.0版本开始支持virtio-mem

5、Libvirt

Libvirt从7.9.0版本开始支持virtio-mem

virtio-mem目标

​ 1、统一所有架构下的内存热插拔(ACPI和virtio)

​ 2、完全在qemu中管理内存大小变化

​ 3、提供安全方法检测恶意guest

​ 4、支持不同大小的内存页/大页

​ 5、支持NUMA

相比于virtio-balloon优点:

​ 1、支持多种内存页大小,甚至在一个guest中不同的virtio-mem设备支持不同的页面大小(64K或者4k)

​ 2、Numa感知

​ 3、能够添加更多内存

​ 4、仅适用于托管内存

​ 5、guest有办法回收内存

virtio-mem架构


上图是 guest的物理地址空间中的virtio-mem设备概述。其中:

  • current size:guest中热插的内存大小
  • requested size:请求热插、热拔的内存大小
  • max region size:保留的内存大小,初始设置最大值
  • usable region size:guest可用于插入、拔出的实际区域大小/可以根据requested size增大到max region size

单独的virtio-mem设备向VM公开动态的内存大小。每个virtio-mem设备像一个更大的DIMM,被划分为固定大小的块,可以处于热插或者热拔的状态。虚拟机Hypervisor和guest OS通过virtio-mem设备进行通信,以协调来自hypervisor的resize request 热插拔块设备。当处理resize 请求时由guest OS 决定选择virtio-mem块设备来进行热插拔。每一个virtio-mem设备通过设备属性公开在guest物理地址空间中的位置。guest os中的设备驱动程序处理virtio-mem设备的检测和通信。当前插入的设备内存大小可以通过设备属性获得,该属性在成功热插拔块之后更新。guest os可以通过比较插入的大小和请求的大小来确定是否该插入或者拔出 内存块。为了在hypervisor中实现优化,设备管理内存区域中只有一部分可能可用于热插块设备:可用区域,也通过设备属性公开。hypervisor可以根据需要增加可用区域。

virtio驱动关系

virtio提供了virtio总线和设备控制面的接口。

virtio_ring提供了数据面,也就是virtqueue接口和对应的vring实现。

virtio_pci提供了virtio设备作为PCI设备加载时的通用驱动入口,它依赖virtio和virtio_ring提供的接口。

virtio_mem提供了virtio内存块设备的标准驱动,它依赖virtio和virtio_ring提供的接口。virtio_mem将自己注册为virtio总线的一种设备驱动

virtio-mem数据结构


DeviceState作为所有设备的父类,派生出VirtioDevice和PCIDevice,virtio-mem派生自VirtioDevice


Qemu模拟PCI总线,同时创建virtio-mem-pci、virtio-net-pci、virtio-scsi-pci等设备,挂载在PCI总线上,并且创建Virtio总线,用于挂载virtio-mem等最终设备

virtio-mem代码流程

在virtio-mem.c中对virtio涉及到的实例和类进行初始化

static const TypeInfo virtio_mem_info = {...//实例初始化.instance_init = virtio_mem_instance_init, //类初始化.class_init = virtio_mem_class_init,      .class_size = sizeof(VirtIOMEMClass),...
};

由于virtio这块实现了类的继承关系,在子类初始化之前,需要先调用父类的实现,上图是继承关系

static void virtio_mem_class_init(ObjectClass *klass, void *data)
{DeviceClass *dc = DEVICE_CLASS(klass);VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);VirtIOMEMClass *vmc = VIRTIO_MEM_CLASS(klass);RamDiscardManagerClass *rdmc = RAM_DISCARD_MANAGER_CLASS(klass);device_class_set_props(dc, virtio_mem_properties);dc->vmsd = &vmstate_virtio_mem;set_bit(DEVICE_CATEGORY_MISC, dc->categories);//设备具象化vdc->realize = virtio_mem_device_realize;//设备去具象化vdc->unrealize = virtio_mem_device_unrealize;//读取配置参数vdc->get_config = virtio_mem_get_config;//获取特性   如ACPIvdc->get_features = virtio_mem_get_features;         vdc->vmsd = &vmstate_virtio_mem_device;             //给virtio_mem_device参数赋值vmc->fill_device_info = virtio_mem_fill_device_info;//获取mem_regionvmc->get_memory_region = virtio_mem_get_memory_region;//增加mem_size 改变通知事件机制vmc->add_size_change_notifier = virtio_mem_add_size_change_notifier; //增加移除 mem_size 通知事件机制vmc->remove_size_change_notifier = virtio_mem_remove_size_change_notifier;  rdmc->get_min_granularity = virtio_mem_rdm_get_min_granularity;         rdmc->is_populated = virtio_mem_rdm_is_populated;                              rdmc->replay_populated = virtio_mem_rdm_replay_populated;           rdmc->replay_discarded = virtio_mem_rdm_replay_discarded;           rdmc->register_listener = virtio_mem_rdm_register_listener;          rdmc->unregister_listener = virtio_mem_rdm_unregister_listener;
}

instance_init


实例化相对较为简单,只负责将后继对象初始化,也即virtio-mem

static void virtio_mem_instance_init(Object *obj)
{VirtIOMEM *vmem = VIRTIO_MEM(obj);vmem->block_size = VIRTIO_MEM_MIN_BLOCK_SIZE;notifier_list_init(&vmem->size_change_notifiers);vmem->precopy_notifier.notify = virtio_mem_precopy_notify;object_property_add(obj, VIRTIO_MEM_SIZE_PROP, "size", virtio_mem_get_size,NULL, NULL, NULL);object_property_add(obj, VIRTIO_MEM_REQUESTED_SIZE_PROP, "size",virtio_mem_get_requested_size,virtio_mem_set_requested_size, NULL, NULL);object_property_add(obj, VIRTIO_MEM_BLOCK_SIZE_PROP, "size",virtio_mem_get_block_size, virtio_mem_set_block_size,NULL, NULL);
}

virtio_mem_device 具现化


realize的调用,在类的继承关系中存在多个realize的函数指针,从父类开始执行,一直调用到子类。

virtio_mem_pci_realize函数 会触发virtio_device_realize的调用,是一个通用的virtio设备实现函数

virtio_mem_device_realize进行virtio通用设置,比如virtio的初始化,virtqueue的创建

virtio_bus_device_plugged表示插入总线时的处理,按照PCI总线配置virtio_mem设备信息

比如,指定具有64G的内存后端ram会导致QEMU使用mmap将匿名内存的64G区域映射到其虚拟地址空间。

static void virtio_mem_device_realize(DeviceState *dev, Error **errp)
{MachineState *ms = MACHINE(qdev_get_machine());int nb_numa_nodes = ms->numa_state ? ms->numa_state->num_nodes : 0;VirtIODevice *vdev = VIRTIO_DEVICE(dev);VirtIOMEM *vmem = VIRTIO_MEM(dev);uint64_t page_size;RAMBlock *rb;int ret;......rb = vmem->memdev->mr.ram_block;page_size = qemu_ram_pagesize(rb);......virtio_mem_resize_usable_region(vmem, vmem->requested_size, true);vmem->bitmap_size = memory_region_size(&vmem->memdev->mr) /vmem->block_size;vmem->bitmap = bitmap_new(vmem->bitmap_size);//初始化virtiovirtio_init(vdev, TYPE_VIRTIO_MEM, VIRTIO_ID_MEM,              sizeof(struct virtio_mem_config));//初始化创建128个virtqueuevmem->vq = virtio_add_queue(vdev, 128, virtio_mem_handle_request);        host_memory_backend_set_mapped(vmem->memdev, true);vmstate_register_ram(&vmem->memdev->mr, DEVICE(vmem));qemu_register_reset(virtio_mem_system_reset, vmem);.......
}

virtio-mem也是PCI 设备

static void virtio_mem_pci_class_init(ObjectClass *klass, void *data)
{DeviceClass *dc = DEVICE_CLASS(klass);VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(klass);//实例化virtio-mem-pci 设备k->realize = virtio_mem_pci_realize;                set_bit(DEVICE_CATEGORY_MISC, dc->categories);pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_MEM;pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;pcidev_k->class_id = PCI_CLASS_OTHERS;//PCI获取地址mdc->get_addr = virtio_mem_pci_get_addr;//设置PCI地址mdc->set_addr = virtio_mem_pci_set_addr;//获取插入的mem pci大小mdc->get_plugged_size = virtio_mem_pci_get_plugged_size; //获取mem region区域mdc->get_memory_region = virtio_mem_pci_get_memory_region;//填充设备信息mdc->fill_device_info = virtio_mem_pci_fill_device_info;mdc->get_min_alignment = virtio_mem_pci_get_min_alignment;
}

一文读懂Virtio-mem相关推荐

  1. 从实验室走向大众,一文读懂Nanopore测序技术的发展及应用

    关键词/Nanopore测序技术    文/基因慧 随着基因测序技术不断突破,二代测序的发展也将基因检测成本大幅降低.理想的测序方法,是对原始DNA模板进行直接.准确的测序,消除PCR扩增带来的偏差, ...

  2. 一文读懂Faster RCNN

    来源:信息网络工程研究中心本文约7500字,建议阅读10+分钟 本文从四个切入点为你介绍Faster R-CNN网络. 经过R-CNN和Fast RCNN的积淀,Ross B. Girshick在20 ...

  3. 福利 | 一文读懂系列文章精选集发布啦!

    大数据时代已经悄然到来,越来越多的人希望学习一定的数据思维和技能来武装自己,虽然各种介绍大数据技术的文章每天都扑面而来,但纷繁又零散的知识常常让我们不知该从何入手:同时,为了感谢和回馈读者朋友对数据派 ...

  4. ​一文读懂EfficientDet

    一文读懂EfficientDet. 今年年初Google Brain团队在 CVPR 2020 上发布了 EfficientDet目标检测模型, EfficientDet是一系列可扩展的高效的目标检测 ...

  5. 一文读懂序列建模(deeplearning.ai)之序列模型与注意力机制

    https://www.toutiao.com/a6663809864260649485/ 作者:Pulkit Sharma,2019年1月21日 翻译:陈之炎 校对:丁楠雅 本文约11000字,建议 ...

  6. AI洞观 | 一文读懂英特尔的AI之路

    AI洞观 | 一文读懂英特尔的AI之路 https://mp.weixin.qq.com/s/E9NqeywzQ4H2XCFFOFcKXw 11月13日-14日,英特尔人工智能大会(AIDC)在北京召 ...

  7. 一文读懂机器学习中的模型偏差

    一文读懂机器学习中的模型偏差 http://blog.sina.com.cn/s/blog_cfa68e330102yz2c.html 在人工智能(AI)和机器学习(ML)领域,将预测模型参与决策过程 ...

  8. 一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现

    一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现 导读:近日,马云.马化腾.李彦宏等互联网大佬纷纷亮相2018世界人工智能大会,并登台演讲.关于人工智能的现状与未来,他们提出了各自的观点,也引 ...

  9. 一文读懂你该了解的5G知识:现在别买5G手机

    来源: 腾讯科技 2019年是中国全力布局5G的一年:三大运营商纷纷搭建基站,手机厂商发布5G手机,部分城市已经开启了5G测试--在电信日这天,腾讯科技联合知乎推出重磅策划,聚焦和5G相关的小知识,精 ...

  10. 语言相关系数显著性_相关性分析在SPSS中的具体操作,一文读懂相关系数的含义及使用——【杏花开生物医药统计】...

    相关性分析介绍 生物和医学统计中,相关分析属于流程前端的探索性分析,研究变量间关系及性质,其结果在为下一步采取何种方法做出指引,为数据挖掘之前的基础工作. 相关系数的选择 相关分析之前,需要先确认变量 ...

最新文章

  1. 微信小程序页面上面的名字怎么改_微信小程序改名方法,小程序名称设置规范...
  2. 成功解决⑧NVIDIA安装程序无法继续 此NVIDL驱动程序与此Windows版本不兼容。 此图形驱动程序无法找到兼吝的图形硬件。
  3. android中ActionBar的几个属性
  4. python面试题总结(5)--数据类型(字典)
  5. linux作为生产力工具_适用于Linux的顶级音乐播放器,可保护隐私的社交媒体替代品,打印技巧,生产力工具等
  6. Minimum Inversion Number 线段树
  7. TCP Socket
  8. Jquery ajax, Axios, Fetch区别之我见
  9. C#几种截取字符串的方法(split 、Substring、Replace、remove)
  10. java jar热加载技术_Java热加载(JRebel)与Devtools热部署
  11. 关于整车上下电流程和电源管理
  12. Poetry of Today3--琵琶行
  13. pandas笔记(3)——DataFrame数据查看,缺失值,异常值,重复值预处理
  14. 2015年南通二级建造师考试报名通知
  15. 专访三维空间雷成老师 | 原来水墨画风格的3D建筑动画可以如此惊艳……
  16. 概率论与数理统计学习笔记——第二章
  17. u3d开发培训要学哪些?
  18. 生鲜巨变:每日优鲜、叮咚买菜、盒马“分道扬镳”?
  19. LeetCode:537. 复数乘法————中等
  20. 用vs完整的搭建一个项目流程(包括多个项目之间的依赖) 方法一

热门文章

  1. C语言:编写程序,判断某一年是否是闰年
  2. 数据库查询:限制显示的行数
  3. javascript三元表达式连写(多重条件判断)
  4. Python与PHP:有什么区别?
  5. 深入理解javascript原型和原型链
  6. 【转】无线路由器信道怎么设置
  7. iPhone手机APP里的音乐怎么导出到电脑
  8. 支付宝二面:使用 try-catch 捕获异常会影响性能吗?90%都会答错
  9. 并查集详解------侠客风云传
  10. linux配置hostname