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