[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 11/32] dma: fix incorrect bh scheduling



From: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>

The following 2 cases should be avoided:

  1. DMAAIOCB has been released but continue_after_map_failure
     schedules a bh for it.
  2. Multiple bh calls are schduled on the same DMAAIOCB.

Signed-off-by: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>
Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 dma-helpers.c |   16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/dma-helpers.c b/dma-helpers.c
index 2a1621b..c9fbbd9 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -50,8 +50,14 @@ typedef struct {
     target_phys_addr_t sg_cur_byte;
     QEMUIOVector iov;
     QEMUBH *bh;
+    int in_use;
 } DMAAIOCB;
 
+static void dma_aio_cb_reset(DMAAIOCB *p)
+{
+    p->in_use = 0;
+}
+
 static void dma_bdrv_cb(void *opaque, int ret);
 
 static void reschedule_dma(void *opaque)
@@ -60,6 +66,10 @@ static void reschedule_dma(void *opaque)
 
     qemu_bh_delete(dbs->bh);
     dbs->bh = NULL;
+
+    if (!dbs->in_use)
+        return;
+
     dma_bdrv_cb(opaque, 0);
 }
 
@@ -67,7 +77,8 @@ static void continue_after_map_failure(void *opaque)
 {
     DMAAIOCB *dbs = (DMAAIOCB *)opaque;
 
-    dbs->bh = qemu_bh_new(reschedule_dma, dbs);
+    if (!dbs->bh)
+        dbs->bh = qemu_bh_new(reschedule_dma, dbs);
     qemu_bh_schedule(dbs->bh);
 }
 
@@ -97,6 +108,7 @@ void dma_bdrv_cb(void *opaque, int ret)
         dbs->common.cb(dbs->common.opaque, ret);
         qemu_iovec_destroy(&dbs->iov);
         qemu_aio_release(dbs);
+        dma_aio_cb_reset(dbs);
         return;
     }
 
@@ -129,6 +141,7 @@ void dma_bdrv_cb(void *opaque, int ret)
     if (!dbs->acb) {
         dma_bdrv_unmap(dbs);
         qemu_iovec_destroy(&dbs->iov);
+        dma_aio_cb_reset(dbs);
         return;
     }
 }
@@ -148,6 +161,7 @@ static BlockDriverAIOCB *dma_bdrv_io(
     dbs->sg_cur_byte = 0;
     dbs->is_write = is_write;
     dbs->bh = NULL;
+    dbs->in_use = 1;
     qemu_iovec_init(&dbs->iov, sg->nsg);
     dma_bdrv_cb(dbs, 0);
     if (!dbs->acb) {
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.