Skip to the content.

• 严格说,热迁移里“跳过 balloon 页”主要不是靠传统 balloon inflate 本身完成的,而是靠 virtio-balloon 的 free-page-hint 迁移优化。

传统 balloon inflate 这条路里,guest 把 PFN 交给 balloon 后,QEMU 在源端只是把对应宿主页做 discard,回收宿主内存 balloon_inflate_page() 里直接调用 ram_block_discard_range();底层通常走 madvise(DONTNEED) 或 fallocate(PUNCH_HOLE), 是“把 host backing 扔掉”,不是直接改迁移位图。

真正让 precopy “别发这些页”的,是 free-page-hint。QEMU 在每轮 precopy 的 dirty bitmap sync 前后插了 notifier :sync 前先停 hint,sync 后再让 guest 开始上报当前 free pages,具体看 virtio_balloon_free_page_hint_notify()。

guest 通过 free-page virtqueue 把空闲页范围发给 QEMU,QEMU 收到后调用 get_free_page_hints -> qemu_guest_free_page_hint(addr, len)。

qemu_guest_free_page_hint() 做的事就是核心: - 把这些页从迁移 dirty bitmap rb->bmap 里清掉; - 同时把对应底层 dirty log 也清掉,避免下一轮 sync 又把它们重新加回来; - 于是这些页后续就不会进入发送队列了。 具体看 qemu_guest_free_page_hint()

另外还有一条独立路径是 RamDiscardManager:对“逻辑上已 unplug/discard”的内存范围,迁移会直接把这些范围从 dirty bitmap 中排除, 具体看 ramblock_dirty_bitmap_clear_discarded_pages() 像 virtio-mem/sparse RAM 的语义,不是普通 balloon free-page-hint 本身。

问题: 首先,这里为什么存在一个单独的机制? 还搞的这么复杂

  1. virtio_balloon_free_page_hint_notify 的作用到底是什么?
  2. 哦,我意识到,现在的热迁移机制本来就可以使用这个来搞了。

这里的 sync 指的是 migration_bitmap_sync_precopy() 里的 dirty log 同步,也就是把底层脏页记录拉进 QEMU 的迁移位图 rb->bmap 也就是 migration/ram.c:migration_bitmap_sync_precopy() 调用顺序是:

  1. PRECOPY_NOTIFY_BEFORE_BITMAP_SYNC
  2. migration_bitmap_sync(…)
  3. PRECOPY_NOTIFY_AFTER_BITMAP_SYNC

virtio_balloon_free_page_hint_notify() 就挂在这两个点上。hw/virtio/virtio-balloon.c:649

更具体地说:

所以它本质上是在划分一个 epoch:

这样做的目的,是避免 free-page hint 和 dirty bitmap sync 交错,导致页被重复加入、漏清,或者跨轮次混在一起。

因为 get_free_page_hints() 即使被调用,也只有在状态是 S_START 时,才会对收到的 in_sg 调 qemu_guest_free_page_hint()。 而 qemu_guest_free_page_hint() 才是真正把这些页从 rb->bmap 里清掉的地方。

也就是 get_free_page_hints 中的结果:

    if (elem->in_num && dev->free_page_hint_status == FREE_PAGE_HINT_S_START) {
        for (i = 0; i < elem->in_num; i++) {
            qemu_guest_free_page_hint(elem->in_sg[i].iov_base,
                                      elem->in_sg[i].iov_len);
        }
    }

问题

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。