summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2003-07-04 19:36:59 -0700
committerLinus Torvalds <torvalds@home.osdl.org>2003-07-04 19:36:59 -0700
commit08f364136f8ebfd780d52960dd4834746190d98a (patch)
tree95001f201ced920596460ea4a37f8e75e78e3d7d
parent4e83dc011fab1ab827a991fadccf581f541bf880 (diff)
[PATCH] allow the IO scheduler to pass an allocation hint to
From: Nick Piggin <piggin@cyberone.com.au> This patch implements a hint so that AS can tell the request allocator to allocate a request even if there are none left (the accounting is quite flexible and easily handles overallocations). elv_may_queue semantics have changed from "the elevator does _not_ want another request allocated" to "the elevator _insists_ that another request is allocated". I couldn't see any harm ;) Now in practice, AS will only allow _1_ request over the limit, because as soon as the request is sent to AS, it stops anticipating.
-rw-r--r--drivers/block/as-iosched.c15
-rw-r--r--drivers/block/elevator.c2
-rw-r--r--drivers/block/ll_rw_blk.c2
3 files changed, 17 insertions, 2 deletions
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
index e6af1f822630..2e5e64fb3b39 100644
--- a/drivers/block/as-iosched.c
+++ b/drivers/block/as-iosched.c
@@ -1641,6 +1641,20 @@ static int as_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
return 1;
}
+static int as_may_queue(request_queue_t *q, int rw)
+{
+ struct as_data *ad = q->elevator.elevator_data;
+ struct as_io_context *aic;
+ if (ad->antic_status == ANTIC_WAIT_REQ ||
+ ad->antic_status == ANTIC_WAIT_NEXT) {
+ aic = get_as_io_context();
+ if (ad->as_io_context == aic)
+ return 1;
+ }
+
+ return 0;
+}
+
static void as_exit(request_queue_t *q, elevator_t *e)
{
struct as_data *ad = e->elevator_data;
@@ -1879,6 +1893,7 @@ elevator_t iosched_as = {
.elevator_latter_req_fn = as_latter_request,
.elevator_set_req_fn = as_set_request,
.elevator_put_req_fn = as_put_request,
+ .elevator_may_queue_fn = as_may_queue,
.elevator_init_fn = as_init,
.elevator_exit_fn = as_exit,
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
index 89af76783943..485561a037fc 100644
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -368,7 +368,7 @@ int elv_may_queue(request_queue_t *q, int rw)
if (e->elevator_may_queue_fn)
return e->elevator_may_queue_fn(q, rw);
- return 1;
+ return 0;
}
void elv_completed_request(request_queue_t *q, struct request *rq)
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 34cd5440d4ab..add1bf6130f1 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -1315,7 +1315,7 @@ static struct request *get_request(request_queue_t *q, int rw, int gfp_mask)
struct request_list *rl = &q->rq;
spin_lock_irq(q->queue_lock);
- if (rl->count[rw] >= q->nr_requests || !elv_may_queue(q, rw)) {
+ if (rl->count[rw] >= q->nr_requests && !elv_may_queue(q, rw)) {
spin_unlock_irq(q->queue_lock);
goto out;
}