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

[Xen-changelog] Fix race in blkfront resume path (watch thread could fire watch during the



# HG changeset patch
# User smh22@xxxxxxxxxxxxxxxxxxxx
# Node ID f6fdb6e0d3c96241354fe87cb264d740dfe4087c
# Parent  51f91ef6c3b5ea1f302340ca4147d5a9f4c4260f
Fix race in blkfront resume path (watch thread could fire watch during the
(short-ish) time that we were in BLKIF_STATE_DISCONNECTED). 

Signed-off-by: Steven Hand <steven@xxxxxxxxxxxxx>

diff -r 51f91ef6c3b5 -r f6fdb6e0d3c9 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Thu Nov 17 
12:32:05 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Thu Nov 17 
13:56:50 2005
@@ -57,6 +57,7 @@
 
 #define BLKIF_STATE_DISCONNECTED 0
 #define BLKIF_STATE_CONNECTED    1
+#define BLKIF_STATE_SUSPENDED    2
 
 #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
     (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
@@ -75,7 +76,7 @@
 static void blkif_restart_queue(void *arg);
 static void blkif_recover(struct blkfront_info *);
 static void blkif_completion(struct blk_shadow *);
-static void blkif_free(struct blkfront_info *);
+static void blkif_free(struct blkfront_info *, int);
 
 
 /**
@@ -144,7 +145,7 @@
 
        DPRINTK("blkfront_resume: %s\n", dev->nodename);
 
-       blkif_free(info);
+       blkif_free(info, 1);
 
        err = talk_to_backend(dev, info);
        if (!err)
@@ -207,7 +208,7 @@
        if (message)
                xenbus_dev_fatal(dev, err, "%s", message);
  destroy_blkring:
-       blkif_free(info);
+       blkif_free(info, 0);
  out:
        return err;
 }
@@ -252,7 +253,7 @@
 
        return 0;
 fail:
-       blkif_free(info);
+       blkif_free(info, 0);
        return err;
 }
 
@@ -295,7 +296,8 @@
        unsigned int binfo;
        int err;
 
-        if (info->connected == BLKIF_STATE_CONNECTED)
+        if( (info->connected == BLKIF_STATE_CONNECTED) || 
+           (info->connected == BLKIF_STATE_SUSPENDED) ) 
                return;
 
        DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
@@ -354,7 +356,7 @@
 
        DPRINTK("blkfront_remove: %s removed\n", dev->nodename);
 
-       blkif_free(info);
+       blkif_free(info, 0);
 
        kfree(info);
 
@@ -569,6 +571,7 @@
                        req->nr_sectors, req->buffer,
                        rq_data_dir(req) ? "write" : "read");
 
+
                blkdev_dequeue_request(req);
                if (blkif_queue_request(req)) {
                        blk_requeue_request(rq, req);
@@ -643,11 +646,12 @@
        return IRQ_HANDLED;
 }
 
-static void blkif_free(struct blkfront_info *info)
+static void blkif_free(struct blkfront_info *info, int suspend)
 {
        /* Prevent new requests being issued until we fix things up. */
        spin_lock_irq(&blkif_io_lock);
-       info->connected = BLKIF_STATE_DISCONNECTED;
+       info->connected = suspend ? 
+               BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED; 
        spin_unlock_irq(&blkif_io_lock);
 
        /* Free resources associated with old device channel. */

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


 


Rackspace

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