Skip to the content.

migration 中一共存在那些 thread

基本上关心这几个 thread :

  1. background-snapshot thread
  2. migration thrasd
  3. incoming coroutine

总结如下结果

Source(发送端

Destination(接收端):coroutine + 线程混合

为什么 precopy 接收用 coroutine 而发送用线程?

核心差别在于谁拥有相关状态的上下文:接收端加载 VM 状态几乎全是在操作主线程拥有的对象(QEMUFile、RAMBlock、设备 vmstate),所以留在主线程里、用 coroutine 做异步等待是侵入最小的方案;发送端的主循环主要是按 dirty bitmap 拷贝内存往 socket 写,自己一个线程跑反而简单,只在需要时通过 BQL/锁 与主线程同步。

为什么 background-snapshot 是一个单独的 thread

  1. background-snapshot 和 outgoing migration 的逻辑很类似,也是在不断的写内存 所以需要一个 thread
  2. 但是 background-snapshot 和 outgoing migration 逻辑差别很大,所以就单独构建了一个 thread

bitmap_mutex 的作用是什么?

RAMState 中的 bitmap_mutex

  1. struct RAMState 定义在 migration/ram.c 中,管理热迁移的状态
  2. 持有两个 PageSearchStatus 分别管理 ```c /* State of RAM for migration / struct RAMState { /
    • PageSearchStatus structures for the channels when send pages.
    • Protected by the bitmap_mutex. */ PageSearchStatus pss[RAM_CHANNEL_MAX];

    // …

    /* number of dirty bits in the bitmap / uint64_t migration_dirty_pages; /

    • Protects:
      • dirty/clear bitmap
      • migration_dirty_pages
      • pss structures */ QemuMutex bitmap_mutex;

    // … ```

bitmap_mutex 一共使用的地方:

这个分析结果和我想象的完全不一样,这相当于 dirty bitmap 的获取和使用也是 mutex 互斥的 这里锁让我豁然开朗啊,原来是给

static int ram_save_iterate(QEMUFile *f, void *opaque)
{
    // ...
    /*
     * We'll take this lock a little bit long, but it's okay for two reasons.
     * Firstly, the only possible other thread to take it is who calls
     * qemu_guest_free_page_hint(), which should be rare; secondly, see
     * MAX_WAIT (if curious, further see commit 4508bd9ed8053ce) below, which
     * guarantees that we'll at least released it in a regular basis.
     */

qemu_guest_free_page_hint() 是 balloon 来优化掉那些不需要热迁移的 page 的。

第二个问题,为什么需要 pss 来跟踪遍历到哪里了,以及为什么需要 bitmap_mutex 来保护?

[ ] migration_bitmap_sync 中的 rcu 是做什么的?

    WITH_QEMU_LOCK_GUARD(&rs->bitmap_mutex) {
        WITH_RCU_READ_LOCK_GUARD() {
            RAMBLOCK_FOREACH_NOT_IGNORED(block) {
                ramblock_sync_dirty_bitmap(rs, block);
            }
            stat64_set(&mig_stats.dirty_bytes_last_sync, ram_bytes_remaining());
        }
    }

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