diff options
Diffstat (limited to 'migration')
-rw-r--r-- | migration/migration.c | 4 | ||||
-rw-r--r-- | migration/ram.c | 19 |
2 files changed, 23 insertions, 0 deletions
diff --git a/migration/migration.c b/migration/migration.c index 68afc07016..2a26a20aaf 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1722,6 +1722,10 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running) */ qemu_savevm_send_ping(ms->to_dst_file, 4); + if (migrate_release_ram()) { + ram_postcopy_migrated_memory_release(ms); + } + ret = qemu_file_get_error(ms->to_dst_file); if (ret) { error_report("postcopy_start: Migration stream errored"); diff --git a/migration/ram.c b/migration/ram.c index c22209db30..67f2efbc59 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -1537,6 +1537,25 @@ void ram_debug_dump_bitmap(unsigned long *todump, bool expected) /* **** functions for postcopy ***** */ +void ram_postcopy_migrated_memory_release(MigrationState *ms) +{ + struct RAMBlock *block; + unsigned long *bitmap = atomic_rcu_read(&migration_bitmap_rcu)->bmap; + + QLIST_FOREACH_RCU(block, &ram_list.blocks, next) { + unsigned long first = block->offset >> TARGET_PAGE_BITS; + unsigned long range = first + (block->used_length >> TARGET_PAGE_BITS); + unsigned long run_start = find_next_zero_bit(bitmap, range, first); + + while (run_start < range) { + unsigned long run_end = find_next_bit(bitmap, range, run_start + 1); + ram_discard_range(NULL, block->idstr, run_start << TARGET_PAGE_BITS, + (run_end - run_start) << TARGET_PAGE_BITS); + run_start = find_next_zero_bit(bitmap, range, run_end + 1); + } + } +} + /* * Callback from postcopy_each_ram_send_discard for each RAMBlock * Note: At this point the 'unsentmap' is the processed bitmap combined |