From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43042) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X2GSo-0006jb-Du for qemu-devel@nongnu.org; Wed, 02 Jul 2014 05:04:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X2GSh-0006Z3-G2 for qemu-devel@nongnu.org; Wed, 02 Jul 2014 05:04:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:10011) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X2GSh-0006Yx-6R for qemu-devel@nongnu.org; Wed, 02 Jul 2014 05:04:19 -0400 Message-ID: <53B3CB04.5040909@redhat.com> Date: Wed, 02 Jul 2014 11:04:04 +0200 From: Paolo Bonzini MIME-Version: 1.0 References: <1404291017-7456-1-git-send-email-arei.gonglei@huawei.com> In-Reply-To: <1404291017-7456-1-git-send-email-arei.gonglei@huawei.com> Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH] ide: fix double free List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: arei.gonglei@huawei.com, qemu-devel@nongnu.org Cc: kwolf@redhat.com, Chenliang , weidong.huang@huawei.com, stefanha@redhat.com Il 02/07/2014 10:50, arei.gonglei@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 = {