QEMU VFIO 内存优化探索与实践

716次阅读  |  发布于4年以前

1 Qemu 使用 VFIO 透传设备时启动慢

在使用 VFIO 透传 PCI 设备时,如果虚机使用普通的 4K 物理页,Qemu 启动速度非常慢。启动 100G 的虚机可能就要几十秒甚至更长时间。

2 通过 Perf 进行性能分析

下面我们通过火焰图来看一下普通内存的 Qemu 启动时间都消耗在哪。

2.1 通过 perf 生成火焰图

$ git clone https://github.com/cobblau/FlameGraph

// 其中 25104 是 qemu 进程号
$ perf record -F 99 -p 25104 -g -- sleep 10
$ perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > xx.svg

2.2 4K 内存火焰图结果与分析

通过火焰图可以看出,时间按消耗主要在两个方面:

3 使用 1G 的巨页内存进行优化

给虚机使用巨页内存可以成功对上面第一条进行优化。

由于云虚机内存都是以 G 为颗粒度的,所以我们可以给虚机提供 1G 的巨页内存。

我们以 450G 内存的虚机为例,使用 1G 巨页内存后,启动时间可以优化到 32s。

再次通过火焰图打印一下使用巨页后的时间消耗。

3.1 巨页内存火焰图结果与分析

可以看到使用巨页后的时间消耗的大头是在内存清零上。

4 通过加速内存清零进行优化

4.1 Qemu 内存申请过程简介

如果没有使用 VFIO 透传设备,Qemu 开机时只是 mmap 出来内存并没有真正占用物理内存。真正占用物理内存是虚机在使用时产生的缺页中断中。

如果使用 VFIO 透传虚机,那么虚机的物理内存要事先分配好并且 pin 住不会让内存产生迁移。

当使用巨页内存时同样会在申请后进行预分配操作,并且在预分配内存的内核代码中进行清零操作。

4.2 Qemu 巨页内存申请调用流程

从上图看到 Qemu 在预分配内存是直接写内存,然后通过内核的缺页中断实现的。

前面提到即便给虚机使用了巨页内存,虚机启动时间仍旧有 30 几秒。那么时间消耗到了哪里了呢?

原因是内核在分配内存的时候由于怕原内存中的数据遭到泄露,所以在分配时对内存进行了清零操作。

通过上面的 “巨页内存火焰图”,我们已经可以看到在缺页中断中 clear_page_erms 占据了相当大的时间,并且代码隐藏的相当隐蔽。

4.3 内核内存清零调用流程

4.4 内存清零过程优化

小伙伴们看看哪种方法适合自己哦。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8