* 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).