From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MVVIu-0001Yd-Rj for qemu-devel@nongnu.org; Mon, 27 Jul 2009 14:52:08 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MVVIq-0001Xz-TT for qemu-devel@nongnu.org; Mon, 27 Jul 2009 14:52:08 -0400 Received: from [199.232.76.173] (port=40809 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MVVIq-0001Xs-Eq for qemu-devel@nongnu.org; Mon, 27 Jul 2009 14:52:04 -0400 Received: from mx2.redhat.com ([66.187.237.31]:37598) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MVVIp-0005MN-L6 for qemu-devel@nongnu.org; Mon, 27 Jul 2009 14:52:04 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n6RIq2jt013970 for ; Mon, 27 Jul 2009 14:52:02 -0400 References: <87zlavax3m.fsf@pike.pond.sub.org> From: Markus Armbruster Date: Mon, 27 Jul 2009 20:51:58 +0200 In-Reply-To: <87zlavax3m.fsf@pike.pond.sub.org> (Markus Armbruster's message of "Thu\, 23 Jul 2009 23\:49\:33 +0200") Message-ID: <871vo26jsh.fsf@pike.pond.sub.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Subject: [Qemu-devel] Re: -drive werror=stop can cause state change handlers run out of order List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gleb Natapov Sketch of a possible fix. Please review carefully, as I'm not exactly and expert on the block code. If this is the way to go, I'll complete it (SCSI & virtio-blk) and submit it properly. diff --git a/hw/ide.c b/hw/ide.c index 1e56786..1fe6116 100644 --- a/hw/ide.c +++ b/hw/ide.c @@ -501,6 +501,7 @@ typedef struct BMDMAState { QEMUIOVector qiov; int64_t sector_num; uint32_t nsector; + QEMUBH *bh; } BMDMAState; typedef struct PCIIDEState { @@ -1109,11 +1118,13 @@ static void ide_sector_write(IDEState *s) } } -static void ide_dma_restart_cb(void *opaque, int running, int reason) +static void ide_dma_restart_bh(void *opaque) { BMDMAState *bm = opaque; - if (!running) - return; + qemu_bh_delete(bm->bh); + bm->bh = NULL; + if (!vm_running) + return; /* FIXME can this happen? */ if (bm->status & BM_STATUS_DMA_RETRY) { bm->status &= ~BM_STATUS_DMA_RETRY; ide_dma_restart(bm->ide_if); @@ -1123,6 +1134,17 @@ static void ide_dma_restart_cb(void *opaque, int running, int reason) } } +static void ide_dma_restart_cb(void *opaque, int running, int reason) +{ + BMDMAState *bm = opaque; + if (!running) + return; + if (!bm->bh) { + bm->bh = qemu_bh_new(ide_dma_restart_bh, bm); + qemu_bh_schedule(bm->bh); + } +} + static void ide_write_dma_cb(void *opaque, int ret) { BMDMAState *bm = opaque;