summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2003-07-04 19:36:03 -0700
committerLinus Torvalds <torvalds@home.osdl.org>2003-07-04 19:36:03 -0700
commit3abbd8ff39f3da75117a35ac50020818ff3ef7a6 (patch)
tree18dd9eb289bc3a60a8ba9a3fe0d7a2ccdc779937
parent3faa61fe2ece423aeda58d42f2b8c998cfb9fa3a (diff)
[PATCH] bring back the batch_requests function
From: Nick Piggin <piggin@cyberone.com.au> The batch_requests function got lost during the merge of the dynamic request allocation patch. We need it for the anticipatory scheduler - when the number of threads exceeds the number of requests, the anticipated-upon task will undesirably sleep in get_request_wait(). And apparently some block devices which use small requests need it so they string a decent number together. Jens has acked this patch.
-rw-r--r--drivers/block/ll_rw_blk.c34
-rw-r--r--include/linux/blkdev.h1
2 files changed, 31 insertions, 4 deletions
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 0f11567e5277..dfd489ea0234 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -51,6 +51,11 @@ static int queue_nr_requests;
unsigned long blk_max_low_pfn, blk_max_pfn;
static wait_queue_head_t congestion_wqh[2];
+static inline int batch_requests(void)
+{
+ return min(BLKDEV_MAX_RQ / 8, 8);
+}
+
/*
* Return the threshold (number of free requests) at which the queue is
* considered to be congested. It include a little hysteresis to keep the
@@ -1180,6 +1185,8 @@ static int blk_init_free_list(request_queue_t *q)
struct request_list *rl = &q->rq;
rl->count[READ] = rl->count[WRITE] = 0;
+ init_waitqueue_head(&rl->wait[READ]);
+ init_waitqueue_head(&rl->wait[WRITE]);
rl->rq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, request_cachep);
@@ -1325,18 +1332,33 @@ out:
}
/*
- * No available requests for this queue, unplug the device.
+ * No available requests for this queue, unplug the device and wait for some
+ * requests to become available.
*/
static struct request *get_request_wait(request_queue_t *q, int rw)
{
+ DEFINE_WAIT(wait);
struct request *rq;
generic_unplug_device(q);
do {
rq = get_request(q, rw, GFP_NOIO);
- if (!rq)
- blk_congestion_wait(rw, HZ / 50);
+ if (!rq) {
+ struct request_list *rl = &q->rq;
+
+ prepare_to_wait_exclusive(&rl->wait[rw], &wait,
+ TASK_UNINTERRUPTIBLE);
+ /*
+ * If _all_ the requests were suddenly returned then
+ * no wakeup will be delivered. So now we're on the
+ * waitqueue, go check for that.
+ */
+ rq = get_request(q, rw, GFP_ATOMIC & ~__GFP_HIGH);
+ if (!rq)
+ io_schedule();
+ finish_wait(&rl->wait[rw], &wait);
+ }
} while (!rq);
return rq;
@@ -1498,8 +1520,12 @@ void __blk_put_request(request_queue_t *q, struct request *req)
blk_free_request(q, req);
rl->count[rw]--;
- if ((BLKDEV_MAX_RQ - rl->count[rw]) >= queue_congestion_off_threshold())
+ if ((BLKDEV_MAX_RQ - rl->count[rw]) >=
+ queue_congestion_off_threshold())
clear_queue_congested(q, rw);
+ if ((BLKDEV_MAX_RQ - rl->count[rw]) >= batch_requests() &&
+ waitqueue_active(&rl->wait[rw]))
+ wake_up(&rl->wait[rw]);
}
}
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 786ea3563752..621a5b042a9c 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -27,6 +27,7 @@ struct request_pm_state;
struct request_list {
int count[2];
mempool_t *rq_pool;
+ wait_queue_head_t wait[2];
};
/*