diff options
author | Peter Xu <peterx@redhat.com> | 2023-10-04 18:02:36 -0400 |
---|---|---|
committer | Juan Quintela <quintela@redhat.com> | 2023-10-11 11:17:05 +0200 |
commit | 1015ff5476ceed0ff76156c1b60e76f9d21db497 (patch) | |
tree | 52cfea94f6d2c7b34174b2475f588de4b1d01e15 | |
parent | f4b897f4854c579cedc4d5ebb6db16c03a1eaeb1 (diff) | |
download | qemu-1015ff5476ceed0ff76156c1b60e76f9d21db497.zip qemu-1015ff5476ceed0ff76156c1b60e76f9d21db497.tar.gz qemu-1015ff5476ceed0ff76156c1b60e76f9d21db497.tar.bz2 |
migration: Remember num of ramblocks to sync during recovery
Instead of only relying on the count of rp_sem, make the counter be part of
RAMState so it can be used in both threads to synchronize on the process.
rp_sem will be further reused in follow up patches, as a way to kick the
main thread, e.g., on recovery failures.
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
Message-ID: <20231004220240.167175-7-peterx@redhat.com>
-rw-r--r-- | migration/ram.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/migration/ram.c b/migration/ram.c index e4bfd39..6c40d9a 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -394,6 +394,14 @@ struct RAMState { /* Queue of outstanding page requests from the destination */ QemuMutex src_page_req_mutex; QSIMPLEQ_HEAD(, RAMSrcPageRequest) src_page_requests; + + /* + * This is only used when postcopy is in recovery phase, to communicate + * between the migration thread and the return path thread on dirty + * bitmap synchronizations. This field is unused in other stages of + * RAM migration. + */ + unsigned int postcopy_bmap_sync_requested; }; typedef struct RAMState RAMState; @@ -4119,20 +4127,20 @@ static int ram_dirty_bitmap_sync_all(MigrationState *s, RAMState *rs) { RAMBlock *block; QEMUFile *file = s->to_dst_file; - int ramblock_count = 0; trace_ram_dirty_bitmap_sync_start(); + qatomic_set(&rs->postcopy_bmap_sync_requested, 0); RAMBLOCK_FOREACH_NOT_IGNORED(block) { qemu_savevm_send_recv_bitmap(file, block->idstr); trace_ram_dirty_bitmap_request(block->idstr); - ramblock_count++; + qatomic_inc(&rs->postcopy_bmap_sync_requested); } trace_ram_dirty_bitmap_sync_wait(); /* Wait until all the ramblocks' dirty bitmap synced */ - while (ramblock_count--) { + while (qatomic_read(&rs->postcopy_bmap_sync_requested)) { qemu_sem_wait(&s->rp_state.rp_sem); } @@ -4159,6 +4167,7 @@ int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *block) unsigned long *le_bitmap, nbits = block->used_length >> TARGET_PAGE_BITS; uint64_t local_size = DIV_ROUND_UP(nbits, 8); uint64_t size, end_mark; + RAMState *rs = ram_state; trace_ram_dirty_bitmap_reload_begin(block->idstr); @@ -4225,6 +4234,8 @@ int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *block) /* We'll recalculate migration_dirty_pages in ram_state_resume_prepare(). */ trace_ram_dirty_bitmap_reload_complete(block->idstr); + qatomic_dec(&rs->postcopy_bmap_sync_requested); + /* * We succeeded to sync bitmap for current ramblock. If this is * the last one to sync, we need to notify the main send thread. |