From patchwork Tue Aug 3 14:46:22 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 60763 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 691CAB6F10 for ; Wed, 4 Aug 2010 00:55:46 +1000 (EST) Received: from localhost ([127.0.0.1]:42275 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OgIu7-0004PQ-Bf for incoming@patchwork.ozlabs.org; Tue, 03 Aug 2010 10:55:43 -0400 Received: from [140.186.70.92] (port=58353 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OgIl8-0007OX-PA for qemu-devel@nongnu.org; Tue, 03 Aug 2010 10:46:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OgIl7-0004mG-Gv for qemu-devel@nongnu.org; Tue, 03 Aug 2010 10:46:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51819) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OgIl7-0004m3-A4 for qemu-devel@nongnu.org; Tue, 03 Aug 2010 10:46:25 -0400 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o73EkNJ4027537 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 3 Aug 2010 10:46:23 -0400 Received: from dhcp-5-188.str.redhat.com (dhcp-5-175.str.redhat.com [10.32.5.175]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o73EkHIH020950; Tue, 3 Aug 2010 10:46:22 -0400 From: Kevin Wolf To: anthony@codemonkey.ws Date: Tue, 3 Aug 2010 16:46:22 +0200 Message-Id: <1280846782-27616-4-git-send-email-kwolf@redhat.com> In-Reply-To: <1280846782-27616-1-git-send-email-kwolf@redhat.com> References: <1280846782-27616-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: kwolf@redhat.com, qemu-devel@nongnu.org Subject: [Qemu-devel] [STABLE 0.13][PATCH 3/3] ide: Avoid canceling IDE DMA X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Andrea Arcangeli The reason for not actually canceling the I/O is because with virtualization and lots of VM running, a guest fs may mistake a overload of the host, as an IDE timeout. So rather than canceling the I/O, it's safer to wait I/O completion and simulate that the I/O has completed just before the io cancellation was requested by the guest. This way if ntfs or an app writes data without checking for -EIO retval, and it thinks the write has succeeded, it's less likely to run into troubles. Similar issues for reads. Furthermore because the DMA operation is splitted into many synchronous aio_read/write if there's more than one entry in the SG table, without this patch the DMA would be cancelled in the middle, something we've no idea if it happens on real hardware too or not. Overall this seems a great risk for zero gain. This approach is sure safer than previous code given we can't pretend all guest fs code out there to check for errors and reply the DMA if it was completed partially, given a timeout would never materialize on a real harddisk unless there are defective blocks (and defective blocks are practically only an issue for reads never for writes in any recent hardware as writing to blocks is the way to fix them) or the harddisk breaks as a whole. Signed-off-by: Izik Eidus Signed-off-by: Andrea Arcangeli Signed-off-by: Kevin Wolf (cherry picked from commit 953844d102f5b682f0835f021f2ed2ad9fb7734c) --- hw/ide/pci.c | 23 +++++++++++++++++++++-- 1 files changed, 21 insertions(+), 2 deletions(-) diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 4331d77..ec90f26 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -40,8 +40,27 @@ void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) printf("%s: 0x%08x\n", __func__, val); #endif if (!(val & BM_CMD_START)) { - /* XXX: do it better */ - ide_dma_cancel(bm); + /* + * We can't cancel Scatter Gather DMA in the middle of the + * operation or a partial (not full) DMA transfer would reach + * the storage so we wait for completion instead (we beahve + * like if the DMA was completed by the time the guest trying + * to cancel dma with bmdma_cmd_writeb with BM_CMD_START not + * set). + * + * In the future we'll be able to safely cancel the I/O if the + * whole DMA operation will be submitted to disk with a single + * aio operation with preadv/pwritev. + */ + if (bm->aiocb) { + qemu_aio_flush(); +#ifdef DEBUG_IDE + if (bm->aiocb) + printf("ide_dma_cancel: aiocb still pending"); + if (bm->status & BM_STATUS_DMAING) + printf("ide_dma_cancel: BM_STATUS_DMAING still pending"); +#endif + } bm->cmd = val & 0x09; } else { if (!(bm->status & BM_STATUS_DMAING)) {