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(¶ms, (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(¤t->mm->mmap_sem);
+
+ if (!blktap_active(tap)) {
+ up_read(¤t->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(¤t->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
|