diff options
| author | Andrew Morton <akpm@osdl.org> | 2003-07-04 19:36:59 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-07-04 19:36:59 -0700 |
| commit | 08f364136f8ebfd780d52960dd4834746190d98a (patch) | |
| tree | 95001f201ced920596460ea4a37f8e75e78e3d7d | |
| parent | 4e83dc011fab1ab827a991fadccf581f541bf880 (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.c | 15 | ||||
| -rw-r--r-- | drivers/block/elevator.c | 2 | ||||
| -rw-r--r-- | drivers/block/ll_rw_blk.c | 2 |
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; } |
