WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] ioemu: Perform emulated IDE flushes async

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] ioemu: Perform emulated IDE flushes asynchronously.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 28 Mar 2008 07:40:08 -0700
Delivery-date: Fri, 28 Mar 2008 07:40:33 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1206697850 0
# Node ID 50efc4b3ffdb7996ab58a4cb6d4d48fed197454f
# Parent  7a3702ff0e8c2c9783de6e24edd79203d5e4c070
ioemu: Perform emulated IDE flushes asynchronously.

Fixes 'Windows Bug Check 0x101 issue' in which a VCPU gets tied up for
so long doing a synchronous flush to disc that it misses critical
timer events.

Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Modified-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>
---
 tools/ioemu/block-qcow.c  |    8 +++++++
 tools/ioemu/block-qcow2.c |    8 +++++++
 tools/ioemu/block-raw.c   |   17 +++++++++++++++
 tools/ioemu/block.c       |   23 ++++++++++++++++++++
 tools/ioemu/block_int.h   |    2 +
 tools/ioemu/hw/ide.c      |   52 ++++++++++++++++++++++++++++++++++++++++------
 tools/ioemu/vl.h          |    2 +
 7 files changed, 106 insertions(+), 6 deletions(-)

diff -r 7a3702ff0e8c -r 50efc4b3ffdb tools/ioemu/block-qcow.c
--- a/tools/ioemu/block-qcow.c  Fri Mar 28 07:34:47 2008 +0000
+++ b/tools/ioemu/block-qcow.c  Fri Mar 28 09:50:50 2008 +0000
@@ -783,6 +783,13 @@ static void qcow_aio_cancel(BlockDriverA
     qemu_aio_release(acb);
 }
 
+static BlockDriverAIOCB *qcow_aio_flush(BlockDriverState *bs,
+        BlockDriverCompletionFunc *cb, void *opaque)
+{
+    BDRVQcowState *s = bs->opaque;
+    return bdrv_aio_flush(s->hd, cb, opaque);
+}
+
 static void qcow_close(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
@@ -957,6 +964,7 @@ BlockDriver bdrv_qcow = {
     .bdrv_aio_read = qcow_aio_read,
     .bdrv_aio_write = qcow_aio_write,
     .bdrv_aio_cancel = qcow_aio_cancel,
+    .bdrv_aio_flush = qcow_aio_flush,
     .aiocb_size = sizeof(QCowAIOCB),
     .bdrv_write_compressed = qcow_write_compressed,
     .bdrv_get_info = qcow_get_info,
diff -r 7a3702ff0e8c -r 50efc4b3ffdb tools/ioemu/block-qcow2.c
--- a/tools/ioemu/block-qcow2.c Fri Mar 28 07:34:47 2008 +0000
+++ b/tools/ioemu/block-qcow2.c Fri Mar 28 09:50:50 2008 +0000
@@ -1005,6 +1005,13 @@ static void qcow_aio_cancel(BlockDriverA
     if (acb->hd_aiocb)
         bdrv_aio_cancel(acb->hd_aiocb);
     qemu_aio_release(acb);
+}
+
+static BlockDriverAIOCB *qcow_aio_flush(BlockDriverState *bs,
+        BlockDriverCompletionFunc *cb, void *opaque)
+{
+    BDRVQcowState *s = bs->opaque;
+    return bdrv_aio_flush(s->hd, cb, opaque);
 }
 
 static void qcow_close(BlockDriverState *bs)
@@ -2241,6 +2248,7 @@ BlockDriver bdrv_qcow2 = {
     .bdrv_aio_read = qcow_aio_read,
     .bdrv_aio_write = qcow_aio_write,
     .bdrv_aio_cancel = qcow_aio_cancel,
+    .bdrv_aio_flush = qcow_aio_flush,
     .aiocb_size = sizeof(QCowAIOCB),
     .bdrv_write_compressed = qcow_write_compressed,
 
diff -r 7a3702ff0e8c -r 50efc4b3ffdb tools/ioemu/block-raw.c
--- a/tools/ioemu/block-raw.c   Fri Mar 28 07:34:47 2008 +0000
+++ b/tools/ioemu/block-raw.c   Fri Mar 28 09:50:50 2008 +0000
@@ -496,6 +496,21 @@ static void raw_aio_cancel(BlockDriverAI
         pacb = &acb->next;
     }
 }
+
+static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
+        BlockDriverCompletionFunc *cb, void *opaque)
+{
+    RawAIOCB *acb;
+
+    acb = raw_aio_setup(bs, 0, NULL, 0, cb, opaque);
+    if (!acb)
+        return NULL;
+    if (aio_fsync(O_SYNC, &acb->aiocb) < 0) {
+        qemu_aio_release(acb);
+        return NULL;
+    }
+    return &acb->common;
+}
 #endif
 
 static void raw_close(BlockDriverState *bs)
@@ -621,6 +636,7 @@ BlockDriver bdrv_raw = {
     .bdrv_aio_read = raw_aio_read,
     .bdrv_aio_write = raw_aio_write,
     .bdrv_aio_cancel = raw_aio_cancel,
+    .bdrv_aio_flush = raw_aio_flush,
     .aiocb_size = sizeof(RawAIOCB),
 #endif
     .protocol_name = "file",
@@ -959,6 +975,7 @@ BlockDriver bdrv_host_device = {
     .bdrv_aio_read = raw_aio_read,
     .bdrv_aio_write = raw_aio_write,
     .bdrv_aio_cancel = raw_aio_cancel,
+    .bdrv_aio_flush = raw_aio_flush,
     .aiocb_size = sizeof(RawAIOCB),
 #endif
     .bdrv_pread = raw_pread,
diff -r 7a3702ff0e8c -r 50efc4b3ffdb tools/ioemu/block.c
--- a/tools/ioemu/block.c       Fri Mar 28 07:34:47 2008 +0000
+++ b/tools/ioemu/block.c       Fri Mar 28 09:50:50 2008 +0000
@@ -48,6 +48,8 @@ static BlockDriverAIOCB *bdrv_aio_write_
         int64_t sector_num, const uint8_t *buf, int nb_sectors,
         BlockDriverCompletionFunc *cb, void *opaque);
 static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
+static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
+        BlockDriverCompletionFunc *cb, void *opaque);
 static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 
                         uint8_t *buf, int nb_sectors);
 static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
@@ -155,6 +157,8 @@ void bdrv_register(BlockDriver *bdrv)
         bdrv->bdrv_read = bdrv_read_em;
         bdrv->bdrv_write = bdrv_write_em;
     }
+    if (!bdrv->bdrv_aio_flush)
+        bdrv->bdrv_aio_flush = bdrv_aio_flush_em;
     bdrv->next = first_drv;
     first_drv = bdrv;
 }
@@ -1138,6 +1142,17 @@ void bdrv_aio_cancel(BlockDriverAIOCB *a
     drv->bdrv_aio_cancel(acb);
 }
 
+BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, 
+                                 BlockDriverCompletionFunc *cb, void *opaque)
+{
+    BlockDriver *drv = bs->drv;
+
+    if (!drv)
+        return NULL;
+
+    return drv->bdrv_aio_flush(bs, cb, opaque);
+}
+
 
 /**************************************************************/
 /* async block device emulation */
@@ -1213,6 +1228,14 @@ static void bdrv_aio_cancel_em(BlockDriv
     qemu_aio_release(acb);
 }
 #endif /* !QEMU_TOOL */
+
+static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
+        BlockDriverCompletionFunc *cb, void *opaque)
+{
+    bdrv_flush(bs);
+    cb(opaque, 0);
+    return NULL;
+}
 
 /**************************************************************/
 /* sync block device emulation */
diff -r 7a3702ff0e8c -r 50efc4b3ffdb tools/ioemu/block_int.h
--- a/tools/ioemu/block_int.h   Fri Mar 28 07:34:47 2008 +0000
+++ b/tools/ioemu/block_int.h   Fri Mar 28 09:50:50 2008 +0000
@@ -49,6 +49,8 @@ struct BlockDriver {
         int64_t sector_num, const uint8_t *buf, int nb_sectors,
         BlockDriverCompletionFunc *cb, void *opaque);
     void (*bdrv_aio_cancel)(BlockDriverAIOCB *acb);
+    BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
+        BlockDriverCompletionFunc *cb, void *opaque);
     int aiocb_size;
 
     const char *protocol_name;
diff -r 7a3702ff0e8c -r 50efc4b3ffdb tools/ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c      Fri Mar 28 07:34:47 2008 +0000
+++ b/tools/ioemu/hw/ide.c      Fri Mar 28 09:50:50 2008 +0000
@@ -751,6 +751,7 @@ static inline void ide_set_irq(IDEState 
 static inline void ide_set_irq(IDEState *s)
 {
     BMDMAState *bm = s->bmdma;
+    if (!s->bs) return; /* yikes */
     if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
         if (bm) {
             bm->status |= BM_STATUS_INT;
@@ -916,6 +917,8 @@ static void ide_read_dma_cb(void *opaque
     int n;
     int64_t sector_num;
 
+    if (!s->bs) return; /* yikes */
+
     n = s->io_buffer_size >> 9;
     sector_num = ide_get_sector(s);
     if (n > 0) {
@@ -1024,6 +1027,8 @@ static void ide_write_dma_cb(void *opaqu
     int n;
     int64_t sector_num;
 
+    if (!s->bs) return; /* yikes */
+
     n = s->io_buffer_size >> 9;
     sector_num = ide_get_sector(s);
     if (n > 0) {
@@ -1070,6 +1075,39 @@ static void ide_sector_write_dma(IDEStat
     s->io_buffer_index = 0;
     s->io_buffer_size = 0;
     ide_dma_start(s, ide_write_dma_cb);
+}
+
+static void ide_device_utterly_broken(IDEState *s) {
+    s->status |= BUSY_STAT;
+    s->bs = NULL;
+    /* This prevents all future commands from working.  All of the
+     * asynchronous callbacks (and ide_set_irq, as a safety measure)
+     * check to see whether this has happened and bail if so.
+     */
+}
+
+static void ide_flush_cb(void *opaque, int ret)
+{
+    IDEState *s = opaque;
+
+    if (!s->bs) return; /* yikes */
+
+    if (ret) {
+        /* We are completely doomed.  The IDE spec does not permit us
+        * to return an error from a flush except via a protocol which
+        * requires us to say where the error is and which
+        * contemplates the guest repeating the flush attempt to
+        * attempt flush the remaining data.  We can't support that
+        * because f(data)sync (which is what the block drivers use
+        * eventually) doesn't report the necessary information or
+        * give us the necessary control.  So we make the disk vanish.
+        */
+       ide_device_utterly_broken(s);
+       return;
+    }
+    else
+        s->status = READY_STAT;
+    ide_set_irq(s);
 }
 
 static void ide_atapi_cmd_ok(IDEState *s)
@@ -1297,6 +1335,8 @@ static void ide_atapi_cmd_read_dma_cb(vo
     BMDMAState *bm = opaque;
     IDEState *s = bm->ide_if;
     int data_offset, n;
+
+    if (!s->bs) return; /* yikes */
 
     if (ret < 0) {
         ide_atapi_io_error(s, ret);
@@ -1703,6 +1743,8 @@ static void cdrom_change_cb(void *opaque
     IDEState *s = opaque;
     int64_t nb_sectors;
 
+    if (!s->bs) return; /* yikes */
+
     /* XXX: send interrupt too */
     bdrv_get_geometry(s->bs, &nb_sectors);
     s->nb_sectors = nb_sectors;
@@ -1806,8 +1848,8 @@ static void ide_ioport_write(void *opaqu
         printf("ide: CMD=%02x\n", val);
 #endif
         s = ide_if->cur_drive;
-        /* ignore commands to non existant slave */
-        if (s != ide_if && !s->bs) 
+        /* ignore commands to non existant device */
+        if (!s->bs) 
             break;
 
         switch(val) {
@@ -1976,10 +2018,8 @@ static void ide_ioport_write(void *opaqu
             break;
         case WIN_FLUSH_CACHE:
         case WIN_FLUSH_CACHE_EXT:
-            if (s->bs)
-                bdrv_flush(s->bs);
-           s->status = READY_STAT;
-            ide_set_irq(s);
+            s->status = BUSY_STAT;
+            bdrv_aio_flush(s->bs, ide_flush_cb, s);
             break;
         case WIN_IDLEIMMEDIATE:
         case WIN_STANDBY:
diff -r 7a3702ff0e8c -r 50efc4b3ffdb tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Fri Mar 28 07:34:47 2008 +0000
+++ b/tools/ioemu/vl.h  Fri Mar 28 09:50:50 2008 +0000
@@ -653,6 +653,8 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDr
                                  const uint8_t *buf, int nb_sectors,
                                  BlockDriverCompletionFunc *cb, void *opaque);
 void bdrv_aio_cancel(BlockDriverAIOCB *acb);
+BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, 
+                                 BlockDriverCompletionFunc *cb, void *opaque);
 
 void qemu_aio_init(void);
 void qemu_aio_poll(void);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] ioemu: Perform emulated IDE flushes asynchronously., Xen patchbot-unstable <=