diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2014-07-15 16:44:26 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2014-08-15 15:07:14 +0200 |
commit | 3c80ca158c96ff902a30883a8933e755988948b1 (patch) | |
tree | c1ccc27a2148e1173950d276838803bc5fafcec8 /thread-pool.c | |
parent | c2e50e3d11a0bf4c973cc30478c1af0f2d5f8e81 (diff) | |
download | qemu-3c80ca158c96ff902a30883a8933e755988948b1.zip qemu-3c80ca158c96ff902a30883a8933e755988948b1.tar.gz qemu-3c80ca158c96ff902a30883a8933e755988948b1.tar.bz2 |
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>
Diffstat (limited to 'thread-pool.c')
-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 4cfd078..23888dc 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; |