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

[Xen-devel] [PATCH 4 of 7] blktap: Make the device destruction path synchronous



blktap: Make the device destruction path synchronous.

diff -r 69301010e4cf -r 6a74cabb7220 drivers/xen/blktap/control.c
--- a/drivers/xen/blktap/control.c      Wed Jun 02 19:45:25 2010 -0700
+++ b/drivers/xen/blktap/control.c      Wed Jun 02 19:45:25 2010 -0700
@@ -163,46 +163,29 @@
 blktap_control_destroy_device(struct blktap *tap)
 {
        int err;
-       unsigned long inuse;
 
        if (!tap)
                return 0;
 
        set_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse);
 
-       for (;;) {
-               inuse = tap->dev_inuse;
-               err   = blktap_device_destroy(tap);
-               if (err)
-                       goto wait;
+       err = blktap_device_destroy(tap);
+       if (err)
+               return err;
 
-               inuse = tap->dev_inuse;
-               err   = blktap_ring_destroy(tap);
-               if (err)
-                       goto wait;
+       err = blktap_sysfs_destroy(tap);
+       if (err)
+               return err;
 
-               inuse = tap->dev_inuse;
-               err   = blktap_sysfs_destroy(tap);
-               if (err)
-                       goto wait;
-
-               break;
-
-       wait:
-               BTDBG("inuse: 0x%lx, dev_inuse: 0x%lx\n",
-                     inuse, tap->dev_inuse);
-               if (wait_event_interruptible(tap->wq, tap->dev_inuse != inuse))
-                       break;
-       }
+       err = blktap_ring_destroy(tap);
+       if (err)
+               return err;
 
        clear_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse);
+       clear_bit(BLKTAP_CONTROL, &tap->dev_inuse);
+       wake_up(&tap->wq);
 
-       if (tap->dev_inuse == (1UL << BLKTAP_CONTROL)) {
-               err = 0;
-               clear_bit(BLKTAP_CONTROL, &tap->dev_inuse);
-       }
-
-       return err;
+       return 0;
 }
 
 static int __init
diff -r 69301010e4cf -r 6a74cabb7220 drivers/xen/blktap/device.c
--- a/drivers/xen/blktap/device.c       Wed Jun 02 19:45:25 2010 -0700
+++ b/drivers/xen/blktap/device.c       Wed Jun 02 19:45:25 2010 -0700
@@ -65,7 +65,7 @@
 
        dev->users--;
        if (test_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse))
-               blktap_device_destroy(tap);
+               blktap_control_destroy_device(tap);
 
        return 0;
 }
@@ -306,7 +306,6 @@
        unsigned long kvaddr;
 
        usr_idx = request->usr_idx;
-       down_write(&tap->ring.vma->vm_mm->mmap_sem);
 
        for (i = 0; i < request->nr_pages; i++) {
                kvaddr = request_to_kaddr(request, i);
@@ -324,13 +323,17 @@
                }
        }
 
-       blktap_device_fast_flush(tap, request);
-       up_write(&tap->ring.vma->vm_mm->mmap_sem);
+       if (blktap_active(tap)) {
+               down_write(&tap->ring.vma->vm_mm->mmap_sem);
+               blktap_device_fast_flush(tap, request);
+               up_write(&tap->ring.vma->vm_mm->mmap_sem);
+       }
 }
 
 /*
  * called if the tapdisk process dies unexpectedly.
  * fail and release any pending requests and disable queue.
+ * may be called from non-tapdisk context.
  */
 void
 blktap_device_fail_pending_requests(struct blktap *tap)
@@ -933,8 +936,11 @@
 
        BTINFO("destroy device %d users %d\n", tap->minor, dev->users);
 
-       if (dev->users)
+       if (dev->users) {
+               blktap_device_fail_pending_requests(tap);
+               blktap_device_restart(tap);
                return -EBUSY;
+       }
 
        spin_lock_irq(&dev->lock);
        /* No more blktap_device_do_request(). */
@@ -952,8 +958,6 @@
        blk_cleanup_queue(gd->queue);
        put_disk(gd);
 
-       wake_up(&tap->wq);
-
        return 0;
 }
 
diff -r 69301010e4cf -r 6a74cabb7220 drivers/xen/blktap/ring.c
--- a/drivers/xen/blktap/ring.c Wed Jun 02 19:45:25 2010 -0700
+++ b/drivers/xen/blktap/ring.c Wed Jun 02 19:45:25 2010 -0700
@@ -161,24 +161,12 @@
        struct blktap *tap = vma_to_blktap(vma);
        struct blktap_ring *ring = &tap->ring;
 
-       blktap_device_fail_pending_requests(tap);  /* fail pending requests */
-       blktap_device_restart(tap);                /* fail deferred requests */
+       BTINFO("unmapping ring %d\n", tap->minor);
+       zap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start, NULL);
+       clear_bit(BLKTAP_RING_VMA, &tap->dev_inuse);
+       ring->vma = NULL;
 
-       zap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start, NULL);
-
-       kfree(ring->foreign_map.map);
-       ring->foreign_map.map = NULL;
-
-       /* Free the ring page. */
-       ClearPageReserved(virt_to_page(ring->ring.sring));
-       free_page((unsigned long)ring->ring.sring);
-
-       BTINFO("unmapping ring %d\n", tap->minor);
-       ring->ring.sring = NULL;
-       ring->vma = NULL;
-       clear_bit(BLKTAP_RING_VMA, &tap->dev_inuse);
-
-       wake_up(&tap->wq);
+       blktap_control_destroy_device(tap);
 }
 
 static struct vm_operations_struct blktap_ring_vm_operations = {
@@ -206,6 +194,9 @@
        if (!test_bit(BLKTAP_CONTROL, &tap->dev_inuse))
                return -ENODEV;
 
+       if (test_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse))
+               return -EBUSY;
+
        /* Only one process can access ring at a time */
        if (test_and_set_bit(BLKTAP_RING_FD, &tap->dev_inuse))
                return -EBUSY;
@@ -224,7 +215,9 @@
        BTINFO("freeing device %d\n", tap->minor);
        clear_bit(BLKTAP_RING_FD, &tap->dev_inuse);
        filp->private_data = NULL;
-       wake_up(&tap->wq);      
+
+       blktap_control_destroy_device(tap);
+
        return 0;
 }
 
diff -r 69301010e4cf -r 6a74cabb7220 drivers/xen/blktap/sysfs.c
--- a/drivers/xen/blktap/sysfs.c        Wed Jun 02 19:45:25 2010 -0700
+++ b/drivers/xen/blktap/sysfs.c        Wed Jun 02 19:45:25 2010 -0700
@@ -96,7 +96,6 @@
                           struct device_attribute *attr,
                           const char *buf, size_t size)
 {
-       int err;
        struct blktap *tap = (struct blktap *)dev_get_drvdata(dev);
 
        if (!tap->ring.dev)
@@ -105,9 +104,13 @@
        if (test_and_set_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse))
                return -EBUSY;
 
-       err = blktap_control_destroy_device(tap);
+       BTDBG("sending tapdisk close message\n");
+       tap->ring.ring.sring->pad[0] = BLKTAP2_RING_MESSAGE_CLOSE;
+       blktap_ring_kick_user(tap);
+       wait_event_interruptible(tap->wq,
+                                !test_bit(BLKTAP_CONTROL, &tap->dev_inuse));
 
-       return (err ? : size);
+       return 0;
 }
 CLASS_DEVICE_ATTR(remove, S_IWUSR, NULL, blktap_sysfs_remove_device);
 
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

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