From patchwork Fri Apr 1 14:32:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Denis V. Lunev" X-Patchwork-Id: 8725261 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 097359F3D1 for ; Fri, 1 Apr 2016 14:32:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4D0092009C for ; Fri, 1 Apr 2016 14:32:39 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7FB2A203C3 for ; Fri, 1 Apr 2016 14:32:38 +0000 (UTC) Received: from localhost ([::1]:44743 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1am07p-0006ob-TJ for patchwork-qemu-devel@patchwork.kernel.org; Fri, 01 Apr 2016 10:32:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47156) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1am07f-0006oN-By for qemu-devel@nongnu.org; Fri, 01 Apr 2016 10:32:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1am07c-0002GF-Qp for qemu-devel@nongnu.org; Fri, 01 Apr 2016 10:32:27 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:38728 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1am07c-0002FR-Ex for qemu-devel@nongnu.org; Fri, 01 Apr 2016 10:32:24 -0400 Received: from irbis.sw.ru ([10.30.2.139]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id u31EWAWf009799; Fri, 1 Apr 2016 17:32:13 +0300 (MSK) From: "Denis V. Lunev" To: qemu-devel@nongnu.org Date: Fri, 1 Apr 2016 17:32:08 +0300 Message-Id: <1459521130-3792-2-git-send-email-den@openvz.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1459521130-3792-1-git-send-email-den@openvz.org> References: <1459521130-3792-1-git-send-email-den@openvz.org> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x X-Received-From: 195.214.232.25 Cc: "Denis V. Lunev" , jsnow@redhat.com, rkagan@virtuozzo.com, Pavel Butsykin Subject: [Qemu-devel] [PATCH 1/3] ide: don't lose pending dma state X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Pavel Butsykin If the migration occurs after the IDE DMA has been set up but before it has been initiated, the state gets lost upon save/restore. Specifically, ->dma_cb callback gets cleared, so, when the guest eventually starts bus mastering, the DMA never completes, causing the guest to time out the operation. OTOH all the infrastructure is already in place to restart the DMA if the migration happens while the DMA is in progress. So reuse that infrastructure, by setting bus->error_status based on ->dma_cmd in pre_save if ->dma_cb callback is already set but DMAING is clear. This will indicate the need for restart and make sure ->dma_cb is restored in ide_restart_bh(); howeover since DMAING is clear the state upon restore will be exactly "ready for DMA" as before the save. Signed-off-by: Pavel Butsykin Reviewed-by: Roman Kagan Signed-off-by: Denis V. Lunev Reviewed-by: John Snow --- hw/ide/core.c | 9 +-------- hw/ide/internal.h | 15 +++++++++++++++ hw/ide/pci.c | 4 ++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index 241e840..8f86036 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -803,14 +803,7 @@ static void ide_dma_cb(void *opaque, int ret) return; } if (ret < 0) { - int op = IDE_RETRY_DMA; - - if (s->dma_cmd == IDE_DMA_READ) - op |= IDE_RETRY_READ; - else if (s->dma_cmd == IDE_DMA_TRIM) - op |= IDE_RETRY_TRIM; - - if (ide_handle_rw_error(s, -ret, op)) { + if (ide_handle_rw_error(s, -ret, ide_dma_cmd_to_retry(s->dma_cmd))) { return; } } diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 86bde26..68c7d0d 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -513,6 +513,21 @@ struct IDEDevice { #define IDE_RETRY_TRIM 0x80 #define IDE_RETRY_HBA 0x100 +static inline uint8_t ide_dma_cmd_to_retry(uint8_t dma_cmd) +{ + switch (dma_cmd) { + case IDE_DMA_READ: + return IDE_RETRY_DMA | IDE_RETRY_READ; + case IDE_DMA_WRITE: + return IDE_RETRY_DMA; + case IDE_DMA_TRIM: + return IDE_RETRY_DMA | IDE_RETRY_TRIM; + default: + break; + } + return 0; +} + static inline IDEState *idebus_active_if(IDEBus *bus) { return bus->ifs + bus->unit; diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 92ffee7..8d56a00 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -308,6 +308,10 @@ static void ide_bmdma_pre_save(void *opaque) BMDMAState *bm = opaque; uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS; + if (!(bm->status & BM_STATUS_DMAING) && bm->dma_cb) { + bm->bus->error_status = + ide_dma_cmd_to_retry(bmdma_active_if(bm)->dma_cmd); + } bm->migration_retry_unit = bm->bus->retry_unit; bm->migration_retry_sector_num = bm->bus->retry_sector_num; bm->migration_retry_nsector = bm->bus->retry_nsector;