@samitouri / QOSamiQemu / commits / 664fe212db

migration: Extract blocktime marking helper

Use new function try_mark_postcopy_blocktim_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 <aadeshveer07@gmail.com> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Juraj Marcin <jmarcin@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Signed-off-by: Fabiano Rosas <farosas@suse.de>

Aadeshveer Singh committed Aug 16, 2026 at 23:16 UTC 664fe212db0a70e365fda767380402d895d8d8fe
3 files changed +44 -22
migration/migration.c
+2 -22
@@ -577,32 +577,12 @@ int migrate_send_rp_req_pages(MigrationIncomingState *mis,
577 RAMBlock *rb, ram_addr_t start, uint64_t haddr,
578 uint32_t tid)
579 {
580 - void *aligned = (void *)(uintptr_t)ROUND_DOWN(haddr, qemu_ram_pagesize(rb));
581 - bool received = false;
582 -
583 - WITH_QEMU_LOCK_GUARD(&mis->page_request_mutex) {
584 - received = ramblock_recv_bitmap_test_byte_offset(rb, start);
585 - if (!received) {
586 - if (!g_tree_lookup(mis->page_requested, aligned)) {
587 - /*
588 - * The page has not been received, and it's not yet in the
589 - * page request list. Queue it. Set the value of element
590 - * to 1, so that things like g_tree_lookup() will return
591 - * TRUE (1) when found.
592 - */
593 - g_tree_insert(mis->page_requested, aligned, (gpointer)1);
594 - qatomic_inc(&mis->page_requested_count);
595 - trace_postcopy_page_req_add(aligned, mis->page_requested_count);
596 - }
597 - mark_postcopy_blocktime_begin(haddr, tid, rb);
598 - }
599 - }
600 -
580 /*
581 + * If not able to mark page for blocktime it must already be present.
582 * If the page is there, skip sending the message. We don't even need the
583 * lock because as long as the page arrived, it'll be there forever.
584 */
605 - if (received) {
585 + if (!try_mark_postcopy_blocktime_begin(mis, rb, start, haddr, tid)) {
586 return 0;
587 }
588
migration/postcopy-ram.c
+39
@@ -1054,6 +1054,37 @@ static void blocktime_fault_inject(PostcopyBlocktimeContext *ctx,
1054 trace_postcopy_blocktime_begin(addr, time, cpu, !!head);
1055 }
1056
1057 +/*
1058 + * Take @page_request_mutex and try marking postcopy blocktime begin.
1059 + * Return true if marking is successful and false if page alredy exists.
1060 + */
1061 +bool try_mark_postcopy_blocktime_begin(MigrationIncomingState *mis,
1062 + RAMBlock *rb, ram_addr_t start,
1063 + uint64_t haddr, uint32_t tid)
1064 +{
1065 + bool received = false;
1066 + void *aligned = (void *)(uintptr_t)ROUND_DOWN(haddr, qemu_ram_pagesize(rb));
1067 +
1068 + WITH_QEMU_LOCK_GUARD(&mis->page_request_mutex) {
1069 + received = ramblock_recv_bitmap_test_byte_offset(rb, start);
1070 + if (!received) {
1071 + if (!g_tree_lookup(mis->page_requested, aligned)) {
1072 + /*
1073 + * The page has not been received, and it's not yet in the
1074 + * page request list. Queue it. Set the value of element
1075 + * to 1, so that things like g_tree_lookup() will return
1076 + * TRUE (1) when found.
1077 + */
1078 + g_tree_insert(mis->page_requested, aligned, (gpointer)1);
1079 + qatomic_inc(&mis->page_requested_count);
1080 + trace_postcopy_page_req_add(aligned, mis->page_requested_count);
1081 + }
1082 + mark_postcopy_blocktime_begin((uint64_t)aligned, tid, rb);
1083 + }
1084 + }
1085 + return !received;
1086 +}
1087 +
1088 /*
1089 * This function is being called when pagefault occurs. It tracks down vCPU
1090 * blocking time. It's protected by @page_request_mutex.
@@ -1749,6 +1780,14 @@ void mark_postcopy_blocktime_begin(uintptr_t addr, uint32_t ptid,
1780 RAMBlock *rb)
1781 {
1782 }
1783 +
1784 +bool try_mark_postcopy_blocktime_begin(MigrationIncomingState *mis,
1785 + RAMBlock *rb, ram_addr_t start,
1786 + uint64_t haddr, uint32_t tid)
1787 +{
1788 + g_assert_not_reached();
1789 + return false;
1790 +}
1791 #endif
1792
1793 /* ------------------------------------------------------------------------- */
migration/postcopy-ram.h
+3
@@ -196,6 +196,9 @@ void postcopy_preempt_new_channel(MigrationIncomingState *mis, QEMUFile *file);
196 void postcopy_preempt_setup(MigrationState *s);
197 int postcopy_preempt_establish_channel(MigrationState *s);
198 bool postcopy_is_paused(MigrationStatus status);
199 +bool try_mark_postcopy_blocktime_begin(MigrationIncomingState *mis,
200 + RAMBlock *rb, ram_addr_t start,
201 + uint64_t haddr, uint32_t tid);
202 void mark_postcopy_blocktime_begin(uintptr_t addr, uint32_t ptid,
203 RAMBlock *rb);
204