qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH for-1.4 stable] block: handle spurious coroutine


From: Paolo Bonzini
Subject: Re: [Qemu-devel] [PATCH for-1.4 stable] block: handle spurious coroutine entries
Date: Mon, 11 Feb 2013 11:16:09 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130110 Thunderbird/17.0.2

Il 09/02/2013 17:44, Stefan Hajnoczi ha scritto:
> bdrv_co_io_em(), bdrv_co_flush(), and bdrv_co_discard() yield the
> coroutine when waiting for aio to complete.  They do not check that the
> request has actually finished.
> 
> In simple cases this works, but it returns early when we get spurious
> wake-ups due to qemu_coroutine_enter() being called from other sources.
> One such example is block-migration.c:process_incoming_migration().
> 
> This patch fixes a segfault on incoming block migration.
> 
> Reported-by: David Pravec <address@hidden>
> Signed-off-by: Stefan Hajnoczi <address@hidden>

I would prefer to have ret initialized to -EINPROGRESS, but since we're
close to release it's easier this way.

Reviewed-by: Paolo Bonzini <address@hidden>

> ---
> This patch is partially fixes block migration.  There is another issue that
> causes block migration to fail with "Unknown flags" at 99%.
> 
>  block.c | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/block.c b/block.c
> index 50dab8e..f2f3b80 100644
> --- a/block.c
> +++ b/block.c
> @@ -3961,6 +3961,7 @@ void qemu_aio_release(void *p)
>  typedef struct CoroutineIOCompletion {
>      Coroutine *coroutine;
>      int ret;
> +    bool done;
>  } CoroutineIOCompletion;
>  
>  static void bdrv_co_io_em_complete(void *opaque, int ret)
> @@ -3968,6 +3969,7 @@ static void bdrv_co_io_em_complete(void *opaque, int 
> ret)
>      CoroutineIOCompletion *co = opaque;
>  
>      co->ret = ret;
> +    co->done = true;
>      qemu_coroutine_enter(co->coroutine, NULL);
>  }
>  
> @@ -3992,7 +3994,9 @@ static int coroutine_fn bdrv_co_io_em(BlockDriverState 
> *bs, int64_t sector_num,
>      if (!acb) {
>          return -EIO;
>      }
> -    qemu_coroutine_yield();
> +    while (!co.done) {
> +        qemu_coroutine_yield();
> +    }
>  
>      return co.ret;
>  }
> @@ -4051,7 +4055,9 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
>          if (acb == NULL) {
>              ret = -EIO;
>          } else {
> -            qemu_coroutine_yield();
> +            while (!co.done) {
> +                qemu_coroutine_yield();
> +            }
>              ret = co.ret;
>          }
>      } else {
> @@ -4161,7 +4167,9 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, 
> int64_t sector_num,
>          if (acb == NULL) {
>              return -EIO;
>          } else {
> -            qemu_coroutine_yield();
> +            while (!co.done) {
> +                qemu_coroutine_yield();
> +            }
>              return co.ret;
>          }
>      } else {
> 




reply via email to

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