[fedora-virt-maint] rpms/qemu/F-11 qemu-dma-aio-cancellation1.patch, NONE, 1.1 qemu-dma-aio-cancellation2.patch, NONE, 1.1 qemu-dma-aio-cancellation3.patch, NONE, 1.1 qemu-dma-aio-cancellation4.patch, NONE, 1.1 qemu.spec, 1.93, 1.94

Mark McLoughlin markmc at fedoraproject.org
Thu May 14 11:00:43 UTC 2009


Author: markmc

Update of /cvs/pkgs/rpms/qemu/F-11
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv7042

Modified Files:
	qemu.spec 
Added Files:
	qemu-dma-aio-cancellation1.patch 
	qemu-dma-aio-cancellation2.patch 
	qemu-dma-aio-cancellation3.patch 
	qemu-dma-aio-cancellation4.patch 
Log Message:
* Thu May 14 2009 Mark McLoughlin <markmc at redhat.com> - 2:0.10.4-4
- Cherry pick more DMA AIO cancellation fixes from upstream (#497170)


qemu-dma-aio-cancellation1.patch:

--- NEW FILE qemu-dma-aio-cancellation1.patch ---
>From 3b92e958482155404cfd134a9608041eed69622a Mon Sep 17 00:00:00 2001
From: Avi Kivity <avi at redhat.com>
Date: Fri, 20 Mar 2009 18:26:12 +0000
Subject: [STABLE][PATCH 1/4] Use vectored aiocb storage to store vector translation state

Now that we have a dedicated acb pool for vector translation acbs, we can
store the vector translation state in the acbs instead of in an external
structure.

Signed-off-by: Avi Kivity <avi at redhat.com>

---
 block.c |   29 ++++++++++++++---------------
 1 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/block.c b/block.c
index b12318f..689ea37 100644
--- a/block.c
+++ b/block.c
@@ -1332,31 +1332,32 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
 /**************************************************************/
 /* async I/Os */
 
-typedef struct VectorTranslationState {
+typedef struct VectorTranslationAIOCB {
+    BlockDriverAIOCB common;
     QEMUIOVector *iov;
     uint8_t *bounce;
     int is_write;
     BlockDriverAIOCB *aiocb;
-    BlockDriverAIOCB *this_aiocb;
-} VectorTranslationState;
+} VectorTranslationAIOCB;
 
-static void bdrv_aio_cancel_vector(BlockDriverAIOCB *acb)
+static void bdrv_aio_cancel_vector(BlockDriverAIOCB *_acb)
 {
-    VectorTranslationState *s = acb->opaque;
+    VectorTranslationAIOCB *acb
+        = container_of(_acb, VectorTranslationAIOCB, common);
 
-    bdrv_aio_cancel(s->aiocb);
+    bdrv_aio_cancel(acb->aiocb);
 }
 
 static void bdrv_aio_rw_vector_cb(void *opaque, int ret)
 {
-    VectorTranslationState *s = opaque;
+    VectorTranslationAIOCB *s = (VectorTranslationAIOCB *)opaque;
 
     if (!s->is_write) {
         qemu_iovec_from_buffer(s->iov, s->bounce, s->iov->size);
     }
     qemu_vfree(s->bounce);
-    s->this_aiocb->cb(s->this_aiocb->opaque, ret);
-    qemu_aio_release(s->this_aiocb);
+    s->common.cb(s->common.opaque, ret);
+    qemu_aio_release(s);
 }
 
 static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
@@ -1368,11 +1369,9 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
                                             int is_write)
 
 {
-    VectorTranslationState *s = qemu_mallocz(sizeof(*s));
-    BlockDriverAIOCB *aiocb = qemu_aio_get_pool(&vectored_aio_pool, bs,
-                                                cb, opaque);
+    VectorTranslationAIOCB *s = qemu_aio_get_pool(&vectored_aio_pool, bs,
+                                                  cb, opaque);
 
-    s->this_aiocb = aiocb;
     s->iov = iov;
     s->bounce = qemu_memalign(512, nb_sectors * 512);
     s->is_write = is_write;
@@ -1384,7 +1383,7 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
         s->aiocb = bdrv_aio_read(bs, sector_num, s->bounce, nb_sectors,
                                  bdrv_aio_rw_vector_cb, s);
     }
-    return aiocb;
+    return &s->common;
 }
 
 BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
@@ -1560,7 +1559,7 @@ static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
 
 void bdrv_init(void)
 {
-    aio_pool_init(&vectored_aio_pool, sizeof(BlockDriverAIOCB),
+    aio_pool_init(&vectored_aio_pool, sizeof(VectorTranslationAIOCB),
                   bdrv_aio_cancel_vector);
 
     bdrv_register(&bdrv_raw);
-- 
1.6.0.6


qemu-dma-aio-cancellation2.patch:

--- NEW FILE qemu-dma-aio-cancellation2.patch ---
>From b591f5930d0eaa93690c5a7acf95e4f5a3e04e06 Mon Sep 17 00:00:00 2001
From: Avi Kivity <avi at redhat.com>
Date: Fri, 20 Mar 2009 18:26:16 +0000
Subject: [STABLE][PATCH 2/4] Move block dma helpers aiocb to store dma state

Use the dedicated dma aiocb to store intermediate state for dma block
transactions.

Signed-off-by: Avi Kivity <avi at redhat.com>

---
 dma-helpers.c |   37 ++++++++++++++++++++-----------------
 1 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/dma-helpers.c b/dma-helpers.c
index 19fa4f0..96a120c 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -39,6 +39,7 @@ void qemu_sglist_destroy(QEMUSGList *qsg)
 }
 
 typedef struct {
+    BlockDriverAIOCB common;
     BlockDriverState *bs;
     BlockDriverAIOCB *acb;
     QEMUSGList *sg;
@@ -48,13 +49,13 @@ typedef struct {
     target_phys_addr_t sg_cur_byte;
     QEMUIOVector iov;
     QEMUBH *bh;
-} DMABlockState;
+} DMAAIOCB;
 
 static void dma_bdrv_cb(void *opaque, int ret);
 
 static void reschedule_dma(void *opaque)
 {
-    DMABlockState *dbs = (DMABlockState *)opaque;
+    DMAAIOCB *dbs = (DMAAIOCB *)opaque;
 
     qemu_bh_delete(dbs->bh);
     dbs->bh = NULL;
@@ -63,7 +64,7 @@ static void reschedule_dma(void *opaque)
 
 static void continue_after_map_failure(void *opaque)
 {
-    DMABlockState *dbs = (DMABlockState *)opaque;
+    DMAAIOCB *dbs = (DMAAIOCB *)opaque;
 
     dbs->bh = qemu_bh_new(reschedule_dma, dbs);
     qemu_bh_schedule(dbs->bh);
@@ -71,11 +72,12 @@ static void continue_after_map_failure(void *opaque)
 
 static void dma_bdrv_cb(void *opaque, int ret)
 {
-    DMABlockState *dbs = (DMABlockState *)opaque;
+    DMAAIOCB *dbs = (DMAAIOCB *)opaque;
     target_phys_addr_t cur_addr, cur_len;
     void *mem;
     int i;
 
+    dbs->acb = NULL;
     dbs->sector_num += dbs->iov.size / 512;
     for (i = 0; i < dbs->iov.niov; ++i) {
         cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base,
@@ -85,10 +87,9 @@ static void dma_bdrv_cb(void *opaque, int ret)
     qemu_iovec_reset(&dbs->iov);
 
     if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
-        dbs->acb->cb(dbs->acb->opaque, ret);
+        dbs->common.cb(dbs->common.opaque, ret);
         qemu_iovec_destroy(&dbs->iov);
-        qemu_aio_release(dbs->acb);
-        qemu_free(dbs);
+        qemu_aio_release(dbs);
         return;
     }
 
@@ -112,11 +113,11 @@ static void dma_bdrv_cb(void *opaque, int ret)
     }
 
     if (dbs->is_write) {
-        bdrv_aio_writev(dbs->bs, dbs->sector_num, &dbs->iov,
-                        dbs->iov.size / 512, dma_bdrv_cb, dbs);
+        dbs->acb = bdrv_aio_writev(dbs->bs, dbs->sector_num, &dbs->iov,
+                                   dbs->iov.size / 512, dma_bdrv_cb, dbs);
     } else {
-        bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov,
-                       dbs->iov.size / 512, dma_bdrv_cb, dbs);
+        dbs->acb = bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov,
+                                  dbs->iov.size / 512, dma_bdrv_cb, dbs);
     }
 }
 
@@ -125,10 +126,10 @@ static BlockDriverAIOCB *dma_bdrv_io(
     BlockDriverCompletionFunc *cb, void *opaque,
     int is_write)
 {
-    DMABlockState *dbs = qemu_malloc(sizeof(*dbs));
+    DMAAIOCB *dbs =  qemu_aio_get_pool(&dma_aio_pool, bs, cb, opaque);
 
+    dbs->acb = NULL;
     dbs->bs = bs;
-    dbs->acb = qemu_aio_get_pool(&dma_aio_pool, bs, cb, opaque);
     dbs->sg = sg;
     dbs->sector_num = sector_num;
     dbs->sg_cur_index = 0;
@@ -137,7 +138,7 @@ static BlockDriverAIOCB *dma_bdrv_io(
     dbs->bh = NULL;
     qemu_iovec_init(&dbs->iov, sg->nsg);
     dma_bdrv_cb(dbs, 0);
-    return dbs->acb;
+    return &dbs->common;
 }
 
 
@@ -157,12 +158,14 @@ BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
 
 static void dma_aio_cancel(BlockDriverAIOCB *acb)
 {
-    DMABlockState *dbs = (DMABlockState *)acb->opaque;
+    DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common);
 
-    bdrv_aio_cancel(dbs->acb);
+    if (dbs->acb) {
+        bdrv_aio_cancel(dbs->acb);
+    }
 }
 
 void dma_helper_init(void)
 {
-    aio_pool_init(&dma_aio_pool, sizeof(BlockDriverAIOCB), dma_aio_cancel);
+    aio_pool_init(&dma_aio_pool, sizeof(DMAAIOCB), dma_aio_cancel);
 }
-- 
1.6.0.6


qemu-dma-aio-cancellation3.patch:

--- NEW FILE qemu-dma-aio-cancellation3.patch ---
>From 2df6efa1790a7a2894707257d2fe67b8d1cfb13a Mon Sep 17 00:00:00 2001
From: Avi Kivity <avi at redhat.com>
Date: Sat, 28 Mar 2009 16:11:20 +0000
Subject: [STABLE][PATCH 3/4] Fix vectored aio bounce handling immediate errors

If a bounced vectored aio fails immediately (the inner aio submission
returning NULL) then the bounce handler erronously returns an aio
request which will never be completed (and which crashes when cancelled).

Fix by detecting that the inner request has failed and propagating the
error.

Signed-off-by: Avi Kivity <avi at redhat.com>

---
 block.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 689ea37..b68a8da 100644
--- a/block.c
+++ b/block.c
@@ -1383,6 +1383,11 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
         s->aiocb = bdrv_aio_read(bs, sector_num, s->bounce, nb_sectors,
                                  bdrv_aio_rw_vector_cb, s);
     }
+    if (!s->aiocb) {
+        qemu_vfree(s->bounce);
+        qemu_aio_release(s);
+        return NULL;
+    }
     return &s->common;
 }
 
-- 
1.6.0.6


qemu-dma-aio-cancellation4.patch:

--- NEW FILE qemu-dma-aio-cancellation4.patch ---
>From eaa874771bb83df639e2937884240a6b05622e3f Mon Sep 17 00:00:00 2001
From: Avi Kivity <avi at redhat.com>
Date: Sat, 28 Mar 2009 16:11:25 +0000
Subject: [STABLE][PATCH 4/4] Fix DMA API when handling an immediate error from block layer

The block layer may signal an immediate error on an asynchronous request
by returning NULL.  The DMA API did not handle this correctly, returning
an AIO request which would never complete (and which would crash if
cancelled).

Fix by detecting the failure and propagating it.

Signed-off-by: Avi Kivity <avi at redhat.com>

---
 dma-helpers.c |   27 +++++++++++++++++++++------
 1 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/dma-helpers.c b/dma-helpers.c
index 96a120c..1469e34 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -70,20 +70,26 @@ static void continue_after_map_failure(void *opaque)
     qemu_bh_schedule(dbs->bh);
 }
 
-static void dma_bdrv_cb(void *opaque, int ret)
+static void dma_bdrv_unmap(DMAAIOCB *dbs)
 {
-    DMAAIOCB *dbs = (DMAAIOCB *)opaque;
-    target_phys_addr_t cur_addr, cur_len;
-    void *mem;
     int i;
 
-    dbs->acb = NULL;
-    dbs->sector_num += dbs->iov.size / 512;
     for (i = 0; i < dbs->iov.niov; ++i) {
         cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base,
                                   dbs->iov.iov[i].iov_len, !dbs->is_write,
                                   dbs->iov.iov[i].iov_len);
     }
+}
+
+void dma_bdrv_cb(void *opaque, int ret)
+{
+    DMAAIOCB *dbs = (DMAAIOCB *)opaque;
+    target_phys_addr_t cur_addr, cur_len;
+    void *mem;
+
+    dbs->acb = NULL;
+    dbs->sector_num += dbs->iov.size / 512;
+    dma_bdrv_unmap(dbs);
     qemu_iovec_reset(&dbs->iov);
 
     if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
@@ -119,6 +125,11 @@ static void dma_bdrv_cb(void *opaque, int ret)
         dbs->acb = bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov,
                                   dbs->iov.size / 512, dma_bdrv_cb, dbs);
     }
+    if (!dbs->acb) {
+        dma_bdrv_unmap(dbs);
+        qemu_iovec_destroy(&dbs->iov);
+        return;
+    }
 }
 
 static BlockDriverAIOCB *dma_bdrv_io(
@@ -138,6 +149,10 @@ static BlockDriverAIOCB *dma_bdrv_io(
     dbs->bh = NULL;
     qemu_iovec_init(&dbs->iov, sg->nsg);
     dma_bdrv_cb(dbs, 0);
+    if (!dbs->acb) {
+        qemu_aio_release(dbs);
+        return NULL;
+    }
     return &dbs->common;
 }
 
-- 
1.6.0.6



Index: qemu.spec
===================================================================
RCS file: /cvs/pkgs/rpms/qemu/F-11/qemu.spec,v
retrieving revision 1.93
retrieving revision 1.94
diff -u -p -r1.93 -r1.94
--- qemu.spec	13 May 2009 14:27:42 -0000	1.93
+++ qemu.spec	14 May 2009 11:00:13 -0000	1.94
@@ -1,7 +1,7 @@
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
 Version: 0.10.4
-Release: 3%{?dist}
+Release: 4%{?dist}
 # Epoch because we pushed a qemu-1.0 package
 Epoch: 2
 License: GPLv2+ and LGPLv2+ and BSD
@@ -29,6 +29,10 @@ Patch13: qemu-roms-more-room-fix-vga-ali
 Patch14: qemu-bios-bigger-roms.patch
 Patch15: qemu-kvm-fix-kerneldir-includes.patch
 Patch16: qemu-fix-load-linux.patch
+Patch17: qemu-dma-aio-cancellation1.patch
+Patch18: qemu-dma-aio-cancellation2.patch
+Patch19: qemu-dma-aio-cancellation3.patch
+Patch20: qemu-dma-aio-cancellation4.patch
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: SDL-devel zlib-devel which texi2html gnutls-devel cyrus-sasl-devel
@@ -225,6 +229,10 @@ such as kvmtrace and kvm_stat.
 %patch14 -p1
 %patch15 -p1
 %patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
 
 %build
 # systems like rhel build system does not have a recent enough linker so
@@ -467,6 +475,9 @@ fi
 %{_mandir}/man1/qemu-img.1*
 
 %changelog
+* Thu May 14 2009 Mark McLoughlin <markmc at redhat.com> - 2:0.10.4-4
+- Cherry pick more DMA AIO cancellation fixes from upstream (#497170)
+
 * Wed May 13 2009 Mark McLoughlin <markmc at redhat.com> - 2:0.10.4-3
 - Fix mixup between kvm.modules and the init script (reported by Rich Jones)
 




More information about the Fedora-virt-maint mailing list