[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [qemu-xen staging-4.13] dma-helpers: ensure AIO callback is invoked after cancellation
commit fbde196c30e4797a51bda046ba514b187963d4ba Author: Paolo Bonzini <pbonzini@xxxxxxxxxx> AuthorDate: Mon Jul 29 23:34:16 2019 +0200 Commit: Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx> CommitDate: Sun Oct 27 23:28:10 2019 -0500 dma-helpers: ensure AIO callback is invoked after cancellation dma_aio_cancel unschedules the BH if there is one, which corresponds to the reschedule_dma case of dma_blk_cb. This can stall the DMA permanently, because dma_complete will never get invoked and therefore nobody will ever invoke the original AIO callback in dbs->common.cb. Fix this by invoking the callback (which is ensured to happen after a bdrv_aio_cancel_async, or done manually in the dbs->bh case), and add assertions to check that the DMA state machine is indeed waiting for dma_complete or reschedule_dma, but never both. Reported-by: John Snow <jsnow@xxxxxxxxxx> Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> Message-id: 20190729213416.1972-1-pbonzini@xxxxxxxxxx Signed-off-by: John Snow <jsnow@xxxxxxxxxx> (cherry picked from commit 539343c0a47e19d5dd64d846d64d084d9793681f) Signed-off-by: Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx> --- dma-helpers.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/dma-helpers.c b/dma-helpers.c index 2d7e02d35e..d3871dc61e 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -90,6 +90,7 @@ static void reschedule_dma(void *opaque) { DMAAIOCB *dbs = (DMAAIOCB *)opaque; + assert(!dbs->acb && dbs->bh); qemu_bh_delete(dbs->bh); dbs->bh = NULL; dma_blk_cb(dbs, 0); @@ -111,15 +112,12 @@ static void dma_complete(DMAAIOCB *dbs, int ret) { trace_dma_complete(dbs, ret, dbs->common.cb); + assert(!dbs->acb && !dbs->bh); dma_blk_unmap(dbs); if (dbs->common.cb) { dbs->common.cb(dbs->common.opaque, ret); } qemu_iovec_destroy(&dbs->iov); - if (dbs->bh) { - qemu_bh_delete(dbs->bh); - dbs->bh = NULL; - } qemu_aio_unref(dbs); } @@ -179,14 +177,21 @@ static void dma_aio_cancel(BlockAIOCB *acb) trace_dma_aio_cancel(dbs); + assert(!(dbs->acb && dbs->bh)); if (dbs->acb) { + /* This will invoke dma_blk_cb. */ blk_aio_cancel_async(dbs->acb); + return; } + if (dbs->bh) { cpu_unregister_map_client(dbs->bh); qemu_bh_delete(dbs->bh); dbs->bh = NULL; } + if (dbs->common.cb) { + dbs->common.cb(dbs->common.opaque, -ECANCELED); + } } static AioContext *dma_get_aio_context(BlockAIOCB *acb) -- generated by git-patchbot for /home/xen/git/qemu-xen.git#staging-4.13
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |