From f345aab137553d2003e8f9a685929d89a1ac7c7a Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Fri, 21 Jun 2013 06:20:11 +0200 Subject: [PATCH 15/21] ide: convert ide_sector_write() to asynchronous I/O RH-Author: Fam Zheng Message-id: <1371795611-7208-16-git-send-email-famz@redhat.com> Patchwork-id: 52089 O-Subject: [PATCH RHEL-6.5 qemu-kvm v3 15/15] ide: convert ide_sector_write() to asynchronous I/O Bugzilla: 956825 RH-Acked-by: Paolo Bonzini RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Laszlo Ersek From: Stefan Hajnoczi 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 Reviewed-by: Paolo Bonzini Reviewed-by: Zhi Yong Wu Tested-by: Richard Davies Signed-off-by: Kevin Wolf (cherry picked from commit e82dabd82e7a8ce0294bce829b3d2dd25eb3a514) Signed-off-by: Fam Zheng Conflicts: hw/ide/core.c --- hw/ide/core.c | 62 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 19 deletions(-) Signed-off-by: Miroslav Rezanina --- hw/ide/core.c | 62 +++++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 43 insertions(+), 19 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index e8c0267..33104ed 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -650,40 +650,40 @@ static void ide_sector_write_timer_cb(void *opaque) ide_set_irq(s->bus); } -static void ide_sector_write(IDEState *s) +static 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->pio_aiocb = NULL; + 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); #ifdef TARGET_I386 if (win2k_install_hack && ((++s->irq_count % 16) == 0)) { @@ -702,6 +702,30 @@ static void ide_sector_write(IDEState *s) } } +static 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); + s->pio_aiocb = bdrv_aio_writev(s->bs, sector_num, &s->qiov, n, + ide_sector_write_cb, s); +} + /* TODO This should be common IDE code */ static void ide_dma_restart_bh(void *opaque) { -- 1.7.1