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-devel

[Xen-devel] [PATCH 1 of 7] blktap: Synchronous queue dispatch

To: Xen <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 1 of 7] blktap: Synchronous queue dispatch
From: Daniel Stodden <daniel.stodden@xxxxxxxxxx>
Date: Thu, 03 Jun 2010 03:12:33 -0000
Cc: Jeremy Fitzhardinge <jeremy@xxxxxxxx>
Delivery-date: Wed, 02 Jun 2010 20:21:13 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1275534752@xxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1275534752@xxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.4.3
blktap: Synchronous queue dispatch.

Move all queue runs into tapdisk context. Queue dispatch moved into
ring.poll. That's not nice, but keeps the toolstack fully
compatible. Won't make much of a difference because the original poll
code wasn't level-triggered either.

Obsoletes/removes:
 * run deferrals and wait_queue.o.
 * blktap.tap_sem.
 * vma.unmap.

Signed-off-by: Jake Wires <jake.wires@xxxxxxxxxx>
Signed-off-by: Daniel Stodden <daniel.stodden@xxxxxxxxxx>

diff -r 16fc7d4e03d6 -r 989a51acce0a drivers/xen/blktap/Makefile
--- a/drivers/xen/blktap/Makefile       Wed Jun 02 19:45:24 2010 -0700
+++ b/drivers/xen/blktap/Makefile       Wed Jun 02 19:45:24 2010 -0700
@@ -1,3 +1,3 @@
 obj-$(CONFIG_XEN_BLKDEV_TAP) := blktap.o
 
-blktap-objs := control.o ring.o wait_queue.o device.o request.o sysfs.o
+blktap-objs := control.o ring.o device.o request.o sysfs.o
diff -r 16fc7d4e03d6 -r 989a51acce0a drivers/xen/blktap/blktap.h
--- a/drivers/xen/blktap/blktap.h       Wed Jun 02 19:45:24 2010 -0700
+++ b/drivers/xen/blktap/blktap.h       Wed Jun 02 19:45:24 2010 -0700
@@ -35,7 +35,6 @@
 #define BLKTAP_PAUSED                7
 #define BLKTAP_SHUTDOWN_REQUESTED    8
 #define BLKTAP_PASSTHROUGH           9
-#define BLKTAP_DEFERRED              10
 
 /* blktap IOCTLs: */
 #define BLKTAP2_IOCTL_KICK_FE        1
@@ -168,8 +167,6 @@
 
        struct blktap_params           params;
 
-       struct rw_semaphore            tap_sem;
-
        struct blktap_ring             ring;
        struct blktap_device           device;
 
@@ -178,7 +175,6 @@
        struct scatterlist             sg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 
        wait_queue_head_t              wq;
-       struct list_head               deferred_queue;
 
        struct blktap_statistics       stats;
 };
@@ -222,6 +218,7 @@
 int blktap_device_destroy(struct blktap *);
 int blktap_device_pause(struct blktap *);
 int blktap_device_resume(struct blktap *);
+int blktap_device_run_queue(struct blktap *);
 void blktap_device_restart(struct blktap *);
 void blktap_device_finish_request(struct blktap *,
                                  struct blkif_response *,
@@ -232,9 +229,6 @@
                                     unsigned, unsigned);
 #endif
 
-void blktap_defer(struct blktap *);
-void blktap_run_deferred(void);
-
 int blktap_request_pool_init(void);
 void blktap_request_pool_free(void);
 int blktap_request_pool_grow(void);
diff -r 16fc7d4e03d6 -r 989a51acce0a drivers/xen/blktap/control.c
--- a/drivers/xen/blktap/control.c      Wed Jun 02 19:45:24 2010 -0700
+++ b/drivers/xen/blktap/control.c      Wed Jun 02 19:45:24 2010 -0700
@@ -20,7 +20,6 @@
 
        memset(tap, 0, sizeof(*tap));
        set_bit(BLKTAP_CONTROL, &tap->dev_inuse);
-       init_rwsem(&tap->tap_sem);
        init_waitqueue_head(&tap->wq);
        atomic_set(&tap->refcnt, 0);
        sg_init_table(tap->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
diff -r 16fc7d4e03d6 -r 989a51acce0a drivers/xen/blktap/device.c
--- a/drivers/xen/blktap/device.c       Wed Jun 02 19:45:24 2010 -0700
+++ b/drivers/xen/blktap/device.c       Wed Jun 02 19:45:24 2010 -0700
@@ -212,9 +212,6 @@
        BUG_ON(ret);
 }
 
-/*
- * tap->tap_sem held on entry
- */
 static void
 blktap_device_fast_flush(struct blktap *tap, struct blktap_request *request)
 {
@@ -302,9 +299,6 @@
                               request->nr_pages << PAGE_SHIFT, NULL);
 }
 
-/*
- * tap->tap_sem held on entry
- */
 static void
 blktap_unmap(struct blktap *tap, struct blktap_request *request)
 {
@@ -349,8 +343,6 @@
        if (!test_bit(BLKTAP_DEVICE, &tap->dev_inuse))
                return;
 
-       down_write(&tap->tap_sem);
-
        dev = &tap->device;
        for (usr_idx = 0; usr_idx < MAX_PENDING_REQS; usr_idx++) {
                request = tap->pending_requests[usr_idx];
@@ -368,8 +360,6 @@
                blktap_request_free(tap, request);
        }
 
-       up_write(&tap->tap_sem);
-
        spin_lock_irq(&dev->lock);
 
        /* fail any future requests */
@@ -379,9 +369,6 @@
        spin_unlock_irq(&dev->lock);
 }
 
-/*
- * tap->tap_sem held on entry
- */
 void
 blktap_device_finish_request(struct blktap *tap,
                             struct blkif_response *res,
@@ -590,9 +577,6 @@
        err = -1;
        memset(&table, 0, sizeof(table));
 
-       if (!blktap_active(tap))
-               goto out;
-
        ring    = &tap->ring;
        usr_idx = request->usr_idx;
        blkif_req.id = usr_idx;
@@ -774,24 +758,24 @@
 #endif
 
 /*
- * dev->lock held on entry
+ * called from tapdisk context
  */
-static void
+int
 blktap_device_run_queue(struct blktap *tap)
 {
-       int queued, err;
+       int err, rv;
        struct request_queue *rq;
        struct request *req;
        struct blktap_ring *ring;
        struct blktap_device *dev;
        struct blktap_request *request;
 
-       queued = 0;
        ring   = &tap->ring;
        dev    = &tap->device;
        rq     = dev->gd->queue;
 
        BTDBG("running queue for %d\n", tap->minor);
+       spin_lock_irq(&dev->lock);
 
        while ((req = blk_peek_request(rq)) != NULL) {
                if (!blk_fs_request(req)) {
@@ -816,7 +800,6 @@
                wait:
                        /* Avoid pointless unplugs. */
                        blk_stop_queue(rq);
-                       blktap_defer(tap);
                        break;
                }
 
@@ -836,27 +819,26 @@
                blk_start_request(req);
 
                spin_unlock_irq(&dev->lock);
-               down_read(&tap->tap_sem);
 
                err = blktap_device_process_request(tap, request, req);
-               if (!err)
-                       queued++;
-               else {
+               if (err) {
                        blktap_device_end_dequeued_request(dev, req, -EIO);
                        blktap_request_free(tap, request);
                }
 
-               up_read(&tap->tap_sem);
                spin_lock_irq(&dev->lock);
        }
 
-       if (queued)
-               blktap_ring_kick_user(tap);
+       spin_unlock_irq(&dev->lock);
+
+       rv = ring->ring.req_prod_pvt -
+               ring->ring.sring->req_prod;
+
+       RING_PUSH_REQUESTS(&ring->ring);
+
+       return rv;
 }
 
-/*
- * dev->lock held on entry
- */
 static void
 blktap_device_do_request(struct request_queue *rq)
 {
@@ -872,13 +854,7 @@
        if (!blktap_active(tap))
                goto fail;
 
-       if (test_bit(BLKTAP_PAUSED, &tap->dev_inuse) ||
-           test_bit(BLKTAP_PAUSE_REQUESTED, &tap->dev_inuse)) {
-               blktap_defer(tap);
-               return;
-       }
-
-       blktap_device_run_queue(tap);
+       blktap_ring_kick_user(tap);
        return;
 
 fail:
@@ -896,18 +872,6 @@
        struct blktap_device *dev;
 
        dev = &tap->device;
-
-       if (blktap_active(tap) && RING_FULL(&tap->ring.ring)) {
-               blktap_defer(tap);
-               return;
-       }
-
-       if (test_bit(BLKTAP_PAUSED, &tap->dev_inuse) ||
-           test_bit(BLKTAP_PAUSE_REQUESTED, &tap->dev_inuse)) {
-               blktap_defer(tap);
-               return;
-       }
-
        spin_lock_irq(&dev->lock);
 
        /* Re-enable calldowns. */
diff -r 16fc7d4e03d6 -r 989a51acce0a drivers/xen/blktap/ring.c
--- a/drivers/xen/blktap/ring.c Wed Jun 02 19:45:24 2010 -0700
+++ b/drivers/xen/blktap/ring.c Wed Jun 02 19:45:24 2010 -0700
@@ -30,7 +30,7 @@
   */
 #define RING_PAGES 1
 
-static int
+static void
 blktap_read_ring(struct blktap *tap)
 {
        /* This is called to read responses from the ring. */
@@ -40,13 +40,9 @@
        struct blktap_ring *ring;
        struct blktap_request *request;
 
-       down_read(&tap->tap_sem);
-
        ring = &tap->ring;
-       if (!ring->vma) {
-               up_read(&tap->tap_sem);
-               return 0;
-       }
+       if (!ring->vma)
+               return;
 
        /* for each outstanding message on the ring  */
        rp = ring->ring.sring->rsp_prod;
@@ -54,7 +50,6 @@
 
        for (rc = ring->ring.rsp_cons; rc != rp; rc++) {
                memcpy(&res, RING_GET_RESPONSE(&ring->ring, rc), sizeof(res));
-               mb(); /* rsp_cons read by RING_FULL() in do_block_io_op(). */
                ++ring->ring.rsp_cons;
 
                usr_idx = (int)res.id;
@@ -70,11 +65,9 @@
                blktap_device_finish_request(tap, &res, request);
        }
 
-       up_read(&tap->tap_sem);
 
-       blktap_run_deferred();
-
-       return 0;
+       blktap_device_restart(tap);
+       return;
 }
 
 static int blktap_ring_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -163,29 +156,14 @@
 }
 
 static void
-blktap_ring_vm_unmap(struct vm_area_struct *vma)
-{
-       struct blktap *tap = vma_to_blktap(vma);
-
-       down_write(&tap->tap_sem);
-       clear_bit(BLKTAP_RING_VMA, &tap->dev_inuse);
-       clear_bit(BLKTAP_PAUSED, &tap->dev_inuse);
-       clear_bit(BLKTAP_PAUSE_REQUESTED, &tap->dev_inuse);
-       up_write(&tap->tap_sem);
-}
-
-static void
 blktap_ring_vm_close(struct vm_area_struct *vma)
 {
        struct blktap *tap = vma_to_blktap(vma);
        struct blktap_ring *ring = &tap->ring;
 
-       blktap_ring_vm_unmap(vma);                 /* fail future requests */
        blktap_device_fail_pending_requests(tap);  /* fail pending requests */
        blktap_device_restart(tap);                /* fail deferred requests */
 
-       down_write(&tap->tap_sem);
-
        zap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start, NULL);
 
        kfree(ring->foreign_map.map);
@@ -198,16 +176,17 @@
        BTINFO("unmapping ring %d\n", tap->minor);
        ring->ring.sring = NULL;
        ring->vma = NULL;
+       clear_bit(BLKTAP_RING_VMA, &tap->dev_inuse);
 
-       up_write(&tap->tap_sem);
+       clear_bit(BLKTAP_PAUSED, &tap->dev_inuse);
+       clear_bit(BLKTAP_PAUSE_REQUESTED, &tap->dev_inuse);
 
        wake_up(&tap->wq);
 }
 
 static struct vm_operations_struct blktap_ring_vm_operations = {
        .close    = blktap_ring_vm_close,
-       .unmap    = blktap_ring_vm_unmap,
-       .fault   = blktap_ring_fault,
+       .fault    = blktap_ring_fault,
        .zap_pte  = blktap_ring_clear_pte,
 };
 
@@ -363,10 +342,8 @@
 {
        struct blktap_ring *ring = &tap->ring;
 
-       down_read(&tap->tap_sem);
        if (ring->ring.sring)
                ring->ring.sring->pad[0] = msg;
-       up_read(&tap->tap_sem);
 }
 
 static int
@@ -381,12 +358,16 @@
        switch(cmd) {
        case BLKTAP2_IOCTL_KICK_FE:
                /* There are fe messages to process. */
-               return blktap_read_ring(tap);
+               blktap_read_ring(tap);
+               return 0;
 
        case BLKTAP2_IOCTL_CREATE_DEVICE:
                if (!arg)
                        return -EINVAL;
 
+               if (!blktap_active(tap))
+                       return -ENODEV;
+
                if (copy_from_user(&params, (struct blktap_params __user *)arg,
                                   sizeof(params))) {
                        BTERR("failed to get params\n");
@@ -473,13 +454,26 @@
 {
        struct blktap *tap = filp->private_data;
        struct blktap_ring *ring = &tap->ring;
+       int work = 0;
+
+       down_read(&current->mm->mmap_sem);
+
+       if (!blktap_active(tap)) {
+               up_read(&current->mm->mmap_sem);
+               force_sig(SIGSEGV, current);
+               return 0;
+       }
 
        poll_wait(filp, &ring->poll_wait, wait);
-       if (ring->ring.sring->pad[0] != 0 ||
-           ring->ring.req_prod_pvt != ring->ring.sring->req_prod) {
-               RING_PUSH_REQUESTS(&ring->ring);
+
+       if (test_bit(BLKTAP_DEVICE, &tap->dev_inuse))
+               work = blktap_device_run_queue(tap);
+
+       up_read(&current->mm->mmap_sem);
+
+       if (work ||
+           ring->ring.sring->pad[0])
                return POLLIN | POLLRDNORM;
-       }
 
        return 0;
 }
diff -r 16fc7d4e03d6 -r 989a51acce0a drivers/xen/blktap/sysfs.c
--- a/drivers/xen/blktap/sysfs.c        Wed Jun 02 19:45:24 2010 -0700
+++ b/drivers/xen/blktap/sysfs.c        Wed Jun 02 19:45:24 2010 -0700
@@ -265,8 +265,6 @@
                       "device users: %d\n", tap->params.capacity,
                       tap->params.sector_size, tap->device.users);
 
-       down_read(&tap->tap_sem);
-
        tmp += sprintf(tmp, "pending requests: %d\n", tap->pending_cnt);
        for (i = 0; i < MAX_PENDING_REQS; i++) {
                struct blktap_request *req = tap->pending_requests[i];
@@ -282,7 +280,6 @@
                               req->time.tv_usec);
        }
 
-       up_read(&tap->tap_sem);
        ret = (tmp - buf) + 1;
 
 out:
diff -r 16fc7d4e03d6 -r 989a51acce0a drivers/xen/blktap/wait_queue.c
--- a/drivers/xen/blktap/wait_queue.c   Wed Jun 02 19:45:24 2010 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-#include <linux/list.h>
-#include <linux/spinlock.h>
-
-#include "blktap.h"
-
-static LIST_HEAD(deferred_work_queue);
-static DEFINE_SPINLOCK(deferred_work_lock);
-
-void
-blktap_run_deferred(void)
-{
-       LIST_HEAD(queue);
-       struct blktap *tap;
-       unsigned long flags;
-
-       spin_lock_irqsave(&deferred_work_lock, flags);
-       list_splice_init(&deferred_work_queue, &queue);
-       list_for_each_entry(tap, &queue, deferred_queue)
-               clear_bit(BLKTAP_DEFERRED, &tap->dev_inuse);
-       spin_unlock_irqrestore(&deferred_work_lock, flags);
-
-       while (!list_empty(&queue)) {
-               tap = list_entry(queue.next, struct blktap, deferred_queue);
-               list_del_init(&tap->deferred_queue);
-               blktap_device_restart(tap);
-       }
-}
-
-void
-blktap_defer(struct blktap *tap)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&deferred_work_lock, flags);
-       if (!test_bit(BLKTAP_DEFERRED, &tap->dev_inuse)) {
-               set_bit(BLKTAP_DEFERRED, &tap->dev_inuse);
-               list_add_tail(&tap->deferred_queue, &deferred_work_queue);
-       }
-       spin_unlock_irqrestore(&deferred_work_lock, flags);
-}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel