Il 02/07/2014 10:50, arei.gong...@huawei.com ha scritto: > if (bus->dma->aiocb) { > -#ifdef DEBUG_AIO > - printf("aio_cancel\n"); > -#endif > - bdrv_aio_cancel(bus->dma->aiocb); > - bus->dma->aiocb = NULL; > + bdrv_drain_all(); > + bdrv_flush_all(); > + assert(bus->dma->aiocb == NULL); > }
This is definitely a heavyweight solution, and in fact the bug should not be there in the first place. See dma_complete: static void dma_complete(DMAAIOCB *dbs, int ret) { trace_dma_complete(dbs, ret, dbs->common.cb); dma_bdrv_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; } if (!dbs->in_cancel) { /* Requests may complete while dma_aio_cancel is in progress. In * this case, the AIOCB should not be released because it is still * referenced by dma_aio_cancel. */ qemu_aio_release(dbs); } } Perhaps something like this? diff --git a/dma-helpers.c b/dma-helpers.c index 53cbe92..21b70d12 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -181,15 +181,15 @@ static void dma_aio_cancel(BlockDriverAIOCB *acb) trace_dma_aio_cancel(dbs); + dbs->in_cancel = true; if (dbs->acb) { BlockDriverAIOCB *acb = dbs->acb; dbs->acb = NULL; - dbs->in_cancel = true; bdrv_aio_cancel(acb); - dbs->in_cancel = false; } dbs->common.cb = NULL; dma_complete(dbs, 0); + qemu_aio_release(dbs); } static const AIOCBInfo dma_aiocb_info = {