[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 20/30] migration: Yield bitmap_mutex properly when sending/sleepi
From: |
Juan Quintela |
Subject: |
[PATCH 20/30] migration: Yield bitmap_mutex properly when sending/sleeping |
Date: |
Tue, 15 Nov 2022 13:12:16 +0100 |
From: Peter Xu <peterx@redhat.com>
Don't take the bitmap mutex when sending pages, or when being throttled by
migration_rate_limit() (which is a bit tricky to call it here in ram code,
but seems still helpful).
It prepares for the possibility of concurrently sending pages in >1 threads
using the function ram_save_host_page() because all threads may need the
bitmap_mutex to operate on bitmaps, so that either sendmsg() or any kind of
qemu_sem_wait() blocking for one thread will not block the other from
progressing.
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
migration/ram.c | 46 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 35 insertions(+), 11 deletions(-)
diff --git a/migration/ram.c b/migration/ram.c
index ebc5664dcc..6428138194 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2480,9 +2480,14 @@ static void postcopy_preempt_reset_channel(RAMState *rs)
* a host page in which case the remainder of the hostpage is sent.
* Only dirty target pages are sent. Note that the host page size may
* be a huge page for this block.
+ *
* The saving stops at the boundary of the used_length of the block
* if the RAMBlock isn't a multiple of the host page size.
*
+ * The caller must be with ram_state.bitmap_mutex held to call this
+ * function. Note that this function can temporarily release the lock, but
+ * when the function is returned it'll make sure the lock is still held.
+ *
* Returns the number of pages written or negative on error
*
* @rs: current RAM state
@@ -2490,6 +2495,7 @@ static void postcopy_preempt_reset_channel(RAMState *rs)
*/
static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss)
{
+ bool page_dirty, preempt_active = postcopy_preempt_active();
int tmppages, pages = 0;
size_t pagesize_bits =
qemu_ram_pagesize(pss->block) >> TARGET_PAGE_BITS;
@@ -2513,22 +2519,40 @@ static int ram_save_host_page(RAMState *rs,
PageSearchStatus *pss)
break;
}
+ page_dirty = migration_bitmap_clear_dirty(rs, pss->block, pss->page);
+
/* Check the pages is dirty and if it is send it */
- if (migration_bitmap_clear_dirty(rs, pss->block, pss->page)) {
+ if (page_dirty) {
+ /*
+ * Properly yield the lock only in postcopy preempt mode
+ * because both migration thread and rp-return thread can
+ * operate on the bitmaps.
+ */
+ if (preempt_active) {
+ qemu_mutex_unlock(&rs->bitmap_mutex);
+ }
tmppages = ram_save_target_page(rs, pss);
- if (tmppages < 0) {
- return tmppages;
+ if (tmppages >= 0) {
+ pages += tmppages;
+ /*
+ * Allow rate limiting to happen in the middle of huge pages if
+ * something is sent in the current iteration.
+ */
+ if (pagesize_bits > 1 && tmppages > 0) {
+ migration_rate_limit();
+ }
}
-
- pages += tmppages;
- /*
- * Allow rate limiting to happen in the middle of huge pages if
- * something is sent in the current iteration.
- */
- if (pagesize_bits > 1 && tmppages > 0) {
- migration_rate_limit();
+ if (preempt_active) {
+ qemu_mutex_lock(&rs->bitmap_mutex);
}
+ } else {
+ tmppages = 0;
+ }
+
+ if (tmppages < 0) {
+ return tmppages;
}
+
pss->page = migration_bitmap_find_dirty(rs, pss->block, pss->page);
} while ((pss->page < hostpage_boundary) &&
offset_in_ramblock(pss->block,
--
2.38.1
- [PATCH 13/30] migration: Use non-atomic ops for clear log bitmap, (continued)
- [PATCH 13/30] migration: Use non-atomic ops for clear log bitmap, Juan Quintela, 2022/11/15
- [PATCH 08/30] Update AVX512 support for xbzrle_encode_buffer, Juan Quintela, 2022/11/15
- [PATCH 15/30] migration: Take bitmap mutex when completing ram migration, Juan Quintela, 2022/11/15
- [PATCH 14/30] migration: Disable multifd explicitly with compression, Juan Quintela, 2022/11/15
- [PATCH 16/30] migration: Add postcopy_preempt_active(), Juan Quintela, 2022/11/15
- [PATCH 17/30] migration: Cleanup xbzrle zero page cache update logic, Juan Quintela, 2022/11/15
- [PATCH 18/30] migration: Trivial cleanup save_page_header() on same block check, Juan Quintela, 2022/11/15
- [PATCH 19/30] migration: Remove RAMState.f references in compression code, Juan Quintela, 2022/11/15
- [PATCH 21/30] migration: Use atomic ops properly for page accountings, Juan Quintela, 2022/11/15
- [PATCH 22/30] migration: Teach PSS about host page, Juan Quintela, 2022/11/15
- [PATCH 20/30] migration: Yield bitmap_mutex properly when sending/sleeping,
Juan Quintela <=
- [PATCH 25/30] migration: Make PageSearchStatus part of RAMState, Juan Quintela, 2022/11/15
- [PATCH 23/30] migration: Introduce pss_channel, Juan Quintela, 2022/11/15
- [PATCH 24/30] migration: Add pss_init(), Juan Quintela, 2022/11/15
- [PATCH 26/30] migration: Move last_sent_block into PageSearchStatus, Juan Quintela, 2022/11/15
- [PATCH 28/30] migration: Remove old preempt code around state maintainance, Juan Quintela, 2022/11/15
- [PATCH 29/30] migration: Drop rs->f, Juan Quintela, 2022/11/15
- [PATCH 27/30] migration: Send requested page directly in rp-return thread, Juan Quintela, 2022/11/15
- [PATCH 30/30] migration: Block migration comment or code is wrong, Juan Quintela, 2022/11/15
- Re: [PATCH 00/30] Migration PULL request, Stefan Hajnoczi, 2022/11/15