aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYury Kotov <yury-kotov@yandex-team.ru>2019-11-25 16:36:32 +0300
committerJuan Quintela <quintela@redhat.com>2020-01-20 09:10:22 +0100
commite65cec5e5d97927d22b39167d3e8edeffc771788 (patch)
tree65baa09279886e048f10dd353e5155108e691973
parent174723ffe586e453f8ed4010ea07bbf79805b63f (diff)
migration/ram: Yield periodically to the main loop
Usually, incoming migration coroutine yields to the main loop while its IO-channel is waiting for data to receive. But there is a case when RAM migration and data receive have the same speed: VM with huge zeroed RAM. In this case, IO-channel won't read and thus the main loop is stuck and for instance, it doesn't respond to QMP commands. For this case, yield periodically, but not too often, so as not to affect the speed of migration. Signed-off-by: Yury Kotov <yury-kotov@yandex-team.ru> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
-rw-r--r--migration/ram.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/migration/ram.c b/migration/ram.c
index 1ec5c10561..5cd066467c 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4246,7 +4246,7 @@ static void colo_flush_ram_cache(void)
*/
static int ram_load_precopy(QEMUFile *f)
{
- int flags = 0, ret = 0, invalid_flags = 0, len = 0;
+ int flags = 0, ret = 0, invalid_flags = 0, len = 0, i = 0;
/* ADVISE is earlier, it shows the source has the postcopy capability on */
bool postcopy_advised = postcopy_is_advised();
if (!migrate_use_compression()) {
@@ -4258,6 +4258,17 @@ static int ram_load_precopy(QEMUFile *f)
void *host = NULL;
uint8_t ch;
+ /*
+ * Yield periodically to let main loop run, but an iteration of
+ * the main loop is expensive, so do it each some iterations
+ */
+ if ((i & 32767) == 0 && qemu_in_coroutine()) {
+ aio_co_schedule(qemu_get_current_aio_context(),
+ qemu_coroutine_self());
+ qemu_coroutine_yield();
+ }
+ i++;
+
addr = qemu_get_be64(f);
flags = addr & ~TARGET_PAGE_MASK;
addr &= TARGET_PAGE_MASK;