All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Stefan Hajnoczi <stefanha@redhat.com>, qemu-devel@nongnu.org
Cc: cornelia.huck@de.ibm.com, borntraeger@de.ibm.com
Subject: Re: [Qemu-devel] [PATCH for-2.4 2/2] AioContext: force event loop iteration using BH
Date: Mon, 27 Jul 2015 19:49:06 +0200	[thread overview]
Message-ID: <55B66F12.2040007@redhat.com> (raw)
In-Reply-To: <1438014819-18125-3-git-send-email-stefanha@redhat.com>



On 27/07/2015 18:33, Stefan Hajnoczi wrote:
> The notify_me optimization introduced in commit eabc97797310
> ("AioContext: fix broken ctx->dispatching optimization") skips
> event_notifier_set() calls when the event loop thread is not blocked in
> ppoll(2).
> 
> This optimization causes a deadlock if two aio_context_acquire() calls
> race.  notify_me = 0 during the race so the winning thread can enter
> ppoll(2) unaware that the other thread is waiting its turn to acquire
> the AioContext.
> 
> This patch forces ppoll(2) to return by scheduling a BH instead of
> calling aio_notify().
> 
> The following deadlock with virtio-blk dataplane is fixed:
> 
>   qemu ... -object iothread,id=iothread0 \
>            -drive if=none,id=drive0,file=test.img,... \
>            -device virtio-blk-pci,iothread=iothread0,drive=drive0
> 
> This command-line results in a hang early on without this patch.
> 
> Thanks to Paolo Bonzini <pbonzini@redhat.com> for investigating this bug
> with me.

You're too good! :)  Series

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

> Cc: Christian Borntraeger <borntraeger@de.ibm.com>
> Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
>  async.c             | 17 +++++++++++++++--
>  include/block/aio.h |  3 +++
>  2 files changed, 18 insertions(+), 2 deletions(-)
> 
> diff --git a/async.c b/async.c
> index 9fab4c6..9ca7095 100644
> --- a/async.c
> +++ b/async.c
> @@ -79,8 +79,10 @@ int aio_bh_poll(AioContext *ctx)
>           * aio_notify again if necessary.
>           */
>          if (!bh->deleted && atomic_xchg(&bh->scheduled, 0)) {
> -            if (!bh->idle)
> +            /* Idle BHs and the notify BH don't count as progress */
> +            if (!bh->idle && bh != ctx->notify_dummy_bh) {
>                  ret = 1;
> +            }
>              bh->idle = 0;
>              bh->cb(bh->opaque);
>          }
> @@ -230,6 +232,8 @@ aio_ctx_finalize(GSource     *source)
>  {
>      AioContext *ctx = (AioContext *) source;
>  
> +    qemu_bh_delete(ctx->notify_dummy_bh);
> +
>      qemu_mutex_lock(&ctx->bh_lock);
>      while (ctx->first_bh) {
>          QEMUBH *next = ctx->first_bh->next;
> @@ -297,8 +301,15 @@ static void aio_timerlist_notify(void *opaque)
>  
>  static void aio_rfifolock_cb(void *opaque)
>  {
> +    AioContext *ctx = opaque;
> +
>      /* Kick owner thread in case they are blocked in aio_poll() */
> -    aio_notify(opaque);
> +    qemu_bh_schedule(ctx->notify_dummy_bh);
> +}
> +
> +static void notify_dummy_bh(void *opaque)
> +{
> +    /* Do nothing, we were invoked just to force the event loop to iterate */
>  }
>  
>  static void event_notifier_dummy_cb(EventNotifier *e)
> @@ -325,6 +336,8 @@ AioContext *aio_context_new(Error **errp)
>      rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx);
>      timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx);
>  
> +    ctx->notify_dummy_bh = aio_bh_new(ctx, notify_dummy_bh, NULL);
> +
>      return ctx;
>  }
>  
> diff --git a/include/block/aio.h b/include/block/aio.h
> index 9dd32e0..400b1b0 100644
> --- a/include/block/aio.h
> +++ b/include/block/aio.h
> @@ -114,6 +114,9 @@ struct AioContext {
>      bool notified;
>      EventNotifier notifier;
>  
> +    /* Scheduling this BH forces the event loop it iterate */
> +    QEMUBH *notify_dummy_bh;
> +
>      /* Thread pool for performing work and receiving completion callbacks */
>      struct ThreadPool *thread_pool;
>  
> 

  reply	other threads:[~2015-07-27 17:49 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-27 16:33 [Qemu-devel] [PATCH for-2.4 0/2] AioContext: fix deadlock after aio_context_acquire() race Stefan Hajnoczi
2015-07-27 16:33 ` [Qemu-devel] [PATCH for-2.4 1/2] AioContext: avoid leaking BHs on cleanup Stefan Hajnoczi
2015-07-27 16:33 ` [Qemu-devel] [PATCH for-2.4 2/2] AioContext: force event loop iteration using BH Stefan Hajnoczi
2015-07-27 17:49   ` Paolo Bonzini [this message]
2015-07-28  7:07 ` [Qemu-devel] [PATCH for-2.4 0/2] AioContext: fix deadlock after aio_context_acquire() race Cornelia Huck
2015-07-28  8:02   ` Cornelia Huck
2015-07-28  8:34     ` Stefan Hajnoczi
2015-07-28 10:26       ` Cornelia Huck
2015-07-28 10:31         ` Stefan Hajnoczi
2015-07-28 10:34           ` Stefan Hajnoczi
2015-07-28 10:58             ` Cornelia Huck
2015-07-28 12:18               ` Paolo Bonzini
2015-07-28 13:58                 ` Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=55B66F12.2040007@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=borntraeger@de.ibm.com \
    --cc=cornelia.huck@de.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.