Use new function try_mark_postcopy_blocktime_begin() to call mark_postcopy_blocktime_begin if page was not received and return if it actually marked it.
This will help in having a cleaner API to call mark_postcopy_blocktime_begin as it requires the page to not be received by asserting on it's existance in RAMBlock->receivedmap. Signed-off-by: Aadeshveer Singh <[email protected]> --- migration/migration.c | 24 ++---------------------- migration/postcopy-ram.c | 31 +++++++++++++++++++++++++++++++ migration/postcopy-ram.h | 3 +++ 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 074d3f2c69..07394d8eea 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -577,32 +577,12 @@ int migrate_send_rp_req_pages(MigrationIncomingState *mis, RAMBlock *rb, ram_addr_t start, uint64_t haddr, uint32_t tid) { - void *aligned = (void *)(uintptr_t)ROUND_DOWN(haddr, qemu_ram_pagesize(rb)); - bool received = false; - - WITH_QEMU_LOCK_GUARD(&mis->page_request_mutex) { - received = ramblock_recv_bitmap_test_byte_offset(rb, start); - if (!received) { - if (!g_tree_lookup(mis->page_requested, aligned)) { - /* - * The page has not been received, and it's not yet in the - * page request list. Queue it. Set the value of element - * to 1, so that things like g_tree_lookup() will return - * TRUE (1) when found. - */ - g_tree_insert(mis->page_requested, aligned, (gpointer)1); - qatomic_inc(&mis->page_requested_count); - trace_postcopy_page_req_add(aligned, mis->page_requested_count); - } - mark_postcopy_blocktime_begin(haddr, tid, rb); - } - } - /* + * If not able to mark page for blocktime it must already be present. * If the page is there, skip sending the message. We don't even need the * lock because as long as the page arrived, it'll be there forever. */ - if (received) { + if (!try_mark_postcopy_blocktime_begin(mis, rb, start, haddr, tid)) { return 0; } diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index 96a65aa976..4b8f882e1e 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -1057,6 +1057,37 @@ static void blocktime_fault_inject(PostcopyBlocktimeContext *ctx, trace_postcopy_blocktime_begin(addr, time, cpu, !!head); } +/* + * Take @page_request_mutex and try marking postcopy blocktime begin. + * Return true if marking is successful and false if page alredy exists. + */ +bool try_mark_postcopy_blocktime_begin(MigrationIncomingState *mis, + RAMBlock *rb, ram_addr_t start, + uint64_t haddr, uint32_t tid) +{ + bool received = false; + void *aligned = (void *)(uintptr_t)ROUND_DOWN(haddr, qemu_ram_pagesize(rb)); + + WITH_QEMU_LOCK_GUARD(&mis->page_request_mutex) { + received = ramblock_recv_bitmap_test_byte_offset(rb, start); + if (!received) { + if (!g_tree_lookup(mis->page_requested, aligned)) { + /* + * The page has not been received, and it's not yet in the + * page request list. Queue it. Set the value of element + * to 1, so that things like g_tree_lookup() will return + * TRUE (1) when found. + */ + g_tree_insert(mis->page_requested, aligned, (gpointer)1); + qatomic_inc(&mis->page_requested_count); + trace_postcopy_page_req_add(aligned, mis->page_requested_count); + } + mark_postcopy_blocktime_begin((uint64_t)aligned, tid, rb); + } + } + return !received; +} + /* * This function is being called when pagefault occurs. It tracks down vCPU * blocking time. It's protected by @page_request_mutex. diff --git a/migration/postcopy-ram.h b/migration/postcopy-ram.h index 98d918713f..ea879f0bc6 100644 --- a/migration/postcopy-ram.h +++ b/migration/postcopy-ram.h @@ -196,6 +196,9 @@ void postcopy_preempt_new_channel(MigrationIncomingState *mis, QEMUFile *file); void postcopy_preempt_setup(MigrationState *s); int postcopy_preempt_establish_channel(MigrationState *s); bool postcopy_is_paused(MigrationStatus status); +bool try_mark_postcopy_blocktime_begin(MigrationIncomingState *mis, + RAMBlock *rb, ram_addr_t start, + uint64_t haddr, uint32_t tid); void mark_postcopy_blocktime_begin(uintptr_t addr, uint32_t ptid, RAMBlock *rb); -- 2.55.0
