Skip to content

Commit

Permalink
migration: Fix possible infinite loop of ram save process
Browse files Browse the repository at this point in the history
When starting ram saving procedure (especially at the completion phase),
always set last_seen_block to non-NULL to make sure we can always correctly
detect the case where "we've migrated all the dirty pages".

Then we'll guarantee both last_seen_block and pss.block will be valid
always before the loop starts.

See the comment in the code for some details.

Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
  • Loading branch information
xzpeter authored and Juan Quintela committed Nov 15, 2022
1 parent a5b6d2f commit 9724a13
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions migration/ram.c
Expand Up @@ -2574,14 +2574,22 @@ static int ram_find_and_save_block(RAMState *rs)
return pages;
}

/*
* Always keep last_seen_block/last_page valid during this procedure,
* because find_dirty_block() relies on these values (e.g., we compare
* last_seen_block with pss.block to see whether we searched all the
* ramblocks) to detect the completion of migration. Having NULL value
* of last_seen_block can conditionally cause below loop to run forever.
*/
if (!rs->last_seen_block) {
rs->last_seen_block = QLIST_FIRST_RCU(&ram_list.blocks);
rs->last_page = 0;
}

pss.block = rs->last_seen_block;
pss.page = rs->last_page;
pss.complete_round = false;

if (!pss.block) {
pss.block = QLIST_FIRST_RCU(&ram_list.blocks);
}

do {
again = true;
found = get_queued_page(rs, &pss);
Expand Down

0 comments on commit 9724a13

Please sign in to comment.