diff options
| author | Andrew Morton <akpm@osdl.org> | 2003-07-04 19:37:40 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-07-04 19:37:40 -0700 |
| commit | e34b0f533d3da5bdff2360c306e4255fed3cbebd (patch) | |
| tree | ed1e32b65e31ece4356496c565cbdb8be9b39ca9 /drivers/block | |
| parent | 07581dd2bdd67146d13a61ca6506c6c8b694666a (diff) | |
[PATCH] block allocation comments
From: Nick Piggin <piggin@cyberone.com.au>
Add some comments to the request allocation code.
Diffstat (limited to 'drivers/block')
| -rw-r--r-- | drivers/block/ll_rw_blk.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 13cc6073bb47..f03a77be82b6 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1315,13 +1315,21 @@ static inline int ioc_batching(struct io_context *ioc) if (!ioc) return 0; + /* + * Make sure the process is able to allocate at least 1 request + * even if the batch times out, otherwise we could theoretically + * lose wakeups. + */ return ioc->nr_batch_requests == BLK_BATCH_REQ || (ioc->nr_batch_requests > 0 && time_before(jiffies, ioc->last_waited + BLK_BATCH_TIME)); } /* - * ioc_set_batching sets ioc to be a new "batcher" if it is not one + * ioc_set_batching sets ioc to be a new "batcher" if it is not one. This + * will cause the process to be a "batcher" on all queues in the system. This + * is the behaviour we want though - once it gets a wakeup it should be given + * a nice run. */ void ioc_set_batching(struct io_context *ioc) { @@ -1364,6 +1372,12 @@ static struct request *get_request(request_queue_t *q, int rw, int gfp_mask) spin_lock_irq(q->queue_lock); if (rl->count[rw]+1 >= q->nr_requests) { + /* + * The queue will fill after this allocation, so set it as + * full, and mark this process as "batching". This process + * will be allowed to complete a batch of requests, others + * will be blocked. + */ if (!blk_queue_full(q, rw)) { ioc_set_batching(ioc); blk_set_queue_full(q, rw); @@ -1372,6 +1386,10 @@ static struct request *get_request(request_queue_t *q, int rw, int gfp_mask) if (blk_queue_full(q, rw) && !ioc_batching(ioc) && !elv_may_queue(q, rw)) { + /* + * The queue is full and the allocating process is not a + * "batcher", and not exempted by the IO scheduler + */ spin_unlock_irq(q->queue_lock); goto out; } @@ -1383,6 +1401,13 @@ static struct request *get_request(request_queue_t *q, int rw, int gfp_mask) rq = blk_alloc_request(q, gfp_mask); if (!rq) { + /* + * Allocation failed presumably due to memory. Undo anything + * we might have messed up. + * + * Allocating task should really be put onto the front of the + * wait queue, but this is pretty rare. + */ spin_lock_irq(q->queue_lock); freed_request(q, rw); spin_unlock_irq(q->queue_lock); @@ -1439,6 +1464,13 @@ static struct request *get_request_wait(request_queue_t *q, int rw) struct io_context *ioc; io_schedule(); + + /* + * After sleeping, we become a "batching" process and + * will be able to allocate at least one request, and + * up to a big batch of them for a small period time. + * See ioc_batching, ioc_set_batching + */ ioc = get_io_context(GFP_NOIO); ioc_set_batching(ioc); put_io_context(ioc); |
