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>
This commit is contained in:
parent
c2e50e3d11
commit
3c80ca158c
@ -185,6 +185,12 @@ restart:
|
|||||||
QLIST_REMOVE(elem, all);
|
QLIST_REMOVE(elem, all);
|
||||||
/* Read state before ret. */
|
/* Read state before ret. */
|
||||||
smp_rmb();
|
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);
|
elem->common.cb(elem->common.opaque, elem->ret);
|
||||||
qemu_aio_release(elem);
|
qemu_aio_release(elem);
|
||||||
goto restart;
|
goto restart;
|
||||||
|
Loading…
Reference in New Issue
Block a user