[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] migration/ram: Yield periodically to the main loop
From: |
Juan Quintela |
Subject: |
Re: [PATCH] migration/ram: Yield periodically to the main loop |
Date: |
Mon, 25 Nov 2019 13:30:23 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) |
Yury Kotov <address@hidden> wrote:
> Usually, incoming migration coroutine yields to the main loop
> when it's IO-channel waits 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 example, 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.
Ouchhhhh
As a workaround, I agree.
As a final solution, I think that it is best to just move the incoming
migration to its own thread, we get trouble like this from time to time :-(
>
> Signed-off-by: Yury Kotov <address@hidden>
> ---
> migration/ram.c | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/migration/ram.c b/migration/ram.c
> index 5078f94490..fed6ef4b22 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -4227,7 +4227,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()) {
> @@ -4239,6 +4239,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) {
> + 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;