qemu-devel
[Top][All Lists]
Advanced

[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;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]