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 <aadeshveer07@gmail.com>
---
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