diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2014-07-15 16:44:26 +0200 |
---|---|---|
committer | Michael Roth <mdroth@linux.vnet.ibm.com> | 2014-09-08 11:23:06 -0500 |
commit | feb633411f808f0c876b27ff4bff00a3eceb2073 (patch) | |
tree | 35e4a025d770384eff93f6260a0308457dc64701 | |
parent | 75ada6b7631bdf5d9f56af845c5096f5d75d33bf (diff) |
thread-pool: avoid deadlock in nested aio_poll() calls
The thread pool has a race condition if two elements complete before
thread_pool_completion_bh() runs:
If element A's callback waits for element B using aio_poll() it will
deadlock since pool->completion_bh is not marked scheduled when the
nested aio_poll() runs.
Fix this by marking the BH scheduled while thread_pool_completion_bh()
is executing. This way any nested aio_poll() loops will enter
thread_pool_completion_bh() and complete the remaining elements.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 3c80ca158c96ff902a30883a8933e755988948b1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
-rw-r--r-- | thread-pool.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/thread-pool.c b/thread-pool.c index 4cfd07893f..23888dcfc4 100644 --- a/thread-pool.c +++ b/thread-pool.c @@ -185,6 +185,12 @@ restart: QLIST_REMOVE(elem, all); /* Read state before ret. */ smp_rmb(); + + /* Schedule ourselves in case elem->common.cb() calls aio_poll() to + * wait for another request that completed at the same time. + */ + qemu_bh_schedule(pool->completion_bh); + elem->common.cb(elem->common.opaque, elem->ret); qemu_aio_release(elem); goto restart; |