OSDN Git Service

thread-pool: avoid deadlock in nested aio_poll() calls
authorStefan Hajnoczi <stefanha@redhat.com>
Tue, 15 Jul 2014 14:44:26 +0000 (16:44 +0200)
committerKevin Wolf <kwolf@redhat.com>
Fri, 15 Aug 2014 13:07:14 +0000 (15:07 +0200)
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>
thread-pool.c

index 4cfd078..23888dc 100644 (file)
@@ -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;