From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:56273) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SCv2v-0005ka-Cr for qemu-devel@nongnu.org; Wed, 28 Mar 2012 11:44:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SCv2o-00021b-TK for qemu-devel@nongnu.org; Wed, 28 Mar 2012 11:44:24 -0400 Received: from e06smtp10.uk.ibm.com ([195.75.94.106]:40913) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SCv2o-0001yy-JV for qemu-devel@nongnu.org; Wed, 28 Mar 2012 11:44:18 -0400 Received: from /spool/local by e06smtp10.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 28 Mar 2012 16:44:14 +0100 Received: from d06av09.portsmouth.uk.ibm.com (d06av09.portsmouth.uk.ibm.com [9.149.37.250]) by d06nrmr1707.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q2SFiCia2703456 for ; Wed, 28 Mar 2012 16:44:12 +0100 Received: from d06av09.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av09.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q2SFiAwG002503 for ; Wed, 28 Mar 2012 09:44:12 -0600 From: Stefan Hajnoczi Date: Wed, 28 Mar 2012 16:43:59 +0100 Message-Id: <1332949439-6781-3-git-send-email-stefanha@linux.vnet.ibm.com> In-Reply-To: <1332949439-6781-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1332949439-6781-1-git-send-email-stefanha@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 2/2] ide: convert ide_sector_write() to asynchronous I/O List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Richard Davies , Chris Webb , Stefan Hajnoczi , Zhi Yong Wu , Paolo Bonzini The IDE PIO write sector code path uses bdrv_write() and hence can make the guest unresponsive while the I/O request is in progress. This patch converts ide_sector_write() to use bdrv_aio_writev() by using the BUSY_STAT bit to tell the guest that the request is in progress. Signed-off-by: Stefan Hajnoczi --- hw/ide/core.c | 60 ++++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 41 insertions(+), 19 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index e188157..9333f13 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -672,40 +672,38 @@ static void ide_sector_write_timer_cb(void *opaque) ide_set_irq(s->bus); } -void ide_sector_write(IDEState *s) +static void ide_sector_write_cb(void *opaque, int ret) { - int64_t sector_num; - int ret, n, n1; - - s->status = READY_STAT | SEEK_STAT; - sector_num = ide_get_sector(s); -#if defined(DEBUG_IDE) - printf("write sector=%" PRId64 "\n", sector_num); -#endif - n = s->nsector; - if (n > s->req_nb_sectors) - n = s->req_nb_sectors; + IDEState *s = opaque; + int n; - bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); - ret = bdrv_write(s->bs, sector_num, s->io_buffer, n); bdrv_acct_done(s->bs, &s->acct); + s->status &= ~BUSY_STAT; + if (ret != 0) { - if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY)) + if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY)) { return; + } } + n = s->nsector; + if (n > s->req_nb_sectors) { + n = s->req_nb_sectors; + } s->nsector -= n; if (s->nsector == 0) { /* no more sectors to write */ ide_transfer_stop(s); } else { - n1 = s->nsector; - if (n1 > s->req_nb_sectors) + int n1 = s->nsector; + if (n1 > s->req_nb_sectors) { n1 = s->req_nb_sectors; - ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write); + } + ide_transfer_start(s, s->io_buffer, n1 * BDRV_SECTOR_SIZE, + ide_sector_write); } - ide_set_sector(s, sector_num + n); + ide_set_sector(s, ide_get_sector(s) + n); if (win2k_install_hack && ((++s->irq_count % 16) == 0)) { /* It seems there is a bug in the Windows 2000 installer HDD @@ -721,6 +719,30 @@ void ide_sector_write(IDEState *s) } } +void ide_sector_write(IDEState *s) +{ + int64_t sector_num; + int n; + + s->status = READY_STAT | SEEK_STAT | BUSY_STAT; + sector_num = ide_get_sector(s); +#if defined(DEBUG_IDE) + printf("sector=%" PRId64 "\n", sector_num); +#endif + n = s->nsector; + if (n > s->req_nb_sectors) { + n = s->req_nb_sectors; + } + + s->iov.iov_base = s->io_buffer; + s->iov.iov_len = n * BDRV_SECTOR_SIZE; + qemu_iovec_init_external(&s->qiov, &s->iov, 1); + + bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); + bdrv_aio_writev(s->bs, sector_num, &s->qiov, n, + ide_sector_write_cb, s); +} + static void ide_flush_cb(void *opaque, int ret) { IDEState *s = opaque; -- 1.7.9.1