qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* Re: [Qemu-devel] [PATCH] thread-pool: fix deadlock when callbacks depends on each other
       [not found] <538A1F71.4080203@beyond.pl>
@ 2014-06-01 18:12 ` Paolo Bonzini
  2014-06-01 19:02   ` Marcin Gibuła
  0 siblings, 1 reply; 4+ messages in thread
From: Paolo Bonzini @ 2014-06-01 18:12 UTC (permalink / raw)
  To: Marcin Gibuła, qemu-devel@nongnu.org; +Cc: Stefan Hajnoczi

Il 31/05/2014 20:29, Marcin Gibuła ha scritto:
>
> @@ -185,6 +191,14 @@ restart:
>          }
>          if (elem->state == THREAD_DONE && elem->common.cb) {
>              QLIST_REMOVE(elem, all);
> +            /* If more completed requests are waiting, notifier needs
> +             * to be rearmed so callback can progress with aio_pool().
> +             */
> +            pool->pending_completions--;
> +            if (pool->pending_completions) {
> +                event_notifier_set(notifier);
> +            }
> +
>              /* Read state before ret.  */
>              smp_rmb();
>              elem->common.cb(elem->common.opaque, elem->ret);

Good catch!  The main problem with the patch is that you need to use 
atomic_inc/atomic_dec to increment and decrement pool->pending_completions.

Secondarily, event_notifier_set is pretty heavy-weight, does it work if 
you wrap the loop like this?

restart:
     QLIST_FOREACH_SAFE(elem, &pool->head, all, next) {
         ...
     }
     if (pool->pending_completions) {
         goto restart;
     }
     event_notifier_test_and_clear(notifier);
     if (pool->pending_completions) {
         event_notifier_set(notifier);
         goto restart;
     }

Finally, the same bug is also in block/linux-aio.c and block/win32-aio.c.

Paolo

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH] thread-pool: fix deadlock when callbacks depends on each other
  2014-06-01 18:12 ` [Qemu-devel] [PATCH] thread-pool: fix deadlock when callbacks depends on each other Paolo Bonzini
@ 2014-06-01 19:02   ` Marcin Gibuła
  2014-06-02 15:32     ` Paolo Bonzini
  0 siblings, 1 reply; 4+ messages in thread
From: Marcin Gibuła @ 2014-06-01 19:02 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel@nongnu.org; +Cc: Stefan Hajnoczi

> Good catch!  The main problem with the patch is that you need to use
> atomic_inc/atomic_dec to increment and decrement pool->pending_completions.

Ok.

> Secondarily, event_notifier_set is pretty heavy-weight, does it work if
> you wrap the loop like this?
>
> restart:
>      QLIST_FOREACH_SAFE(elem, &pool->head, all, next) {
>          ...
>      }
>      if (pool->pending_completions) {
>          goto restart;
>      }
>      event_notifier_test_and_clear(notifier);
>      if (pool->pending_completions) {
>          event_notifier_set(notifier);
>          goto restart;
>      }

I'll test it tomorrow. I assume you want to avoid calling 
event_notifier_set() until function is reentered via aio_pool?

 > Finally, the same bug is also in block/linux-aio.c and
 > block/win32-aio.c.

I can try with linux-aio, but my knowledge of windows api is zero...

-- 
mg

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH] thread-pool: fix deadlock when callbacks depends on each other
  2014-06-01 19:02   ` Marcin Gibuła
@ 2014-06-02 15:32     ` Paolo Bonzini
  2014-06-02 15:57       ` Marcin Gibuła
  0 siblings, 1 reply; 4+ messages in thread
From: Paolo Bonzini @ 2014-06-02 15:32 UTC (permalink / raw)
  To: Marcin Gibuła, qemu-devel@nongnu.org; +Cc: Stefan Hajnoczi

Il 01/06/2014 21:02, Marcin Gibuła ha scritto:
>> Good catch!  The main problem with the patch is that you need to use
>> atomic_inc/atomic_dec to increment and decrement
>> pool->pending_completions.
>
> Ok.
>
>> Secondarily, event_notifier_set is pretty heavy-weight, does it work if
>> you wrap the loop like this?
>>
>> restart:
>>      QLIST_FOREACH_SAFE(elem, &pool->head, all, next) {
>>          ...
>>      }
>>      if (pool->pending_completions) {
>>          goto restart;
>>      }
>>      event_notifier_test_and_clear(notifier);
>>      if (pool->pending_completions) {
>>          event_notifier_set(notifier);
>>          goto restart;
>>      }
>
> I'll test it tomorrow. I assume you want to avoid calling
> event_notifier_set() until function is reentered via aio_pool?

Yes.  But actually, I need to check if it's possible to fix 
bdrv_drain_all.  If you're in coroutine context, you can defer the 
draining to a safe point using a bottom half.  If you're not in 
coroutine context, perhaps bdrv_drain_all has to be made illegal.  Which 
means a bunch of code auditing...

Paolo

>> Finally, the same bug is also in block/linux-aio.c and
>> block/win32-aio.c.
>
> I can try with linux-aio, but my knowledge of windows api is zero...
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH] thread-pool: fix deadlock when callbacks depends on each other
  2014-06-02 15:32     ` Paolo Bonzini
@ 2014-06-02 15:57       ` Marcin Gibuła
  0 siblings, 0 replies; 4+ messages in thread
From: Marcin Gibuła @ 2014-06-02 15:57 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel@nongnu.org; +Cc: Stefan Hajnoczi

>> I'll test it tomorrow. I assume you want to avoid calling
>> event_notifier_set() until function is reentered via aio_pool?
>
> Yes.  But actually, I need to check if it's possible to fix
> bdrv_drain_all.  If you're in coroutine context, you can defer the
> draining to a safe point using a bottom half.  If you're not in
> coroutine context, perhaps bdrv_drain_all has to be made illegal.  Which
> means a bunch of code auditing...

For what it's worth, your solution also works fine, I couldn't recreate 
hang with it. Updated patch proposal posted earlier today.

-- 
mg

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-06-02 15:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <538A1F71.4080203@beyond.pl>
2014-06-01 18:12 ` [Qemu-devel] [PATCH] thread-pool: fix deadlock when callbacks depends on each other Paolo Bonzini
2014-06-01 19:02   ` Marcin Gibuła
2014-06-02 15:32     ` Paolo Bonzini
2014-06-02 15:57       ` Marcin Gibuła

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).