aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/ll_rw_blk.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2005-06-27 04:55:12 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-27 17:33:29 -0400
commit22e2c507c301c3dbbcf91b4948b88f78842ee6c9 (patch)
tree9a97c91d1362e69703aa286021daffb8a5456f4c /drivers/block/ll_rw_blk.c
parent020f46a39eb7b99a575b9f4d105fce2b142acdf1 (diff)
[PATCH] Update cfq io scheduler to time sliced design
This updates the CFQ io scheduler to the new time sliced design (cfq v3). It provides full process fairness, while giving excellent aggregate system throughput even for many competing processes. It supports io priorities, either inherited from the cpu nice value or set directly with the ioprio_get/set syscalls. The latter closely mimic set/getpriority. This import is based on my latest from -mm. Signed-off-by: Jens Axboe <axboe@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/block/ll_rw_blk.c')
-rw-r--r--drivers/block/ll_rw_blk.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 60e64091de1b..234fdcfbdf01 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -276,6 +276,7 @@ static inline void rq_init(request_queue_t *q, struct request *rq)
276 rq->errors = 0; 276 rq->errors = 0;
277 rq->rq_status = RQ_ACTIVE; 277 rq->rq_status = RQ_ACTIVE;
278 rq->bio = rq->biotail = NULL; 278 rq->bio = rq->biotail = NULL;
279 rq->ioprio = 0;
279 rq->buffer = NULL; 280 rq->buffer = NULL;
280 rq->ref_count = 1; 281 rq->ref_count = 1;
281 rq->q = q; 282 rq->q = q;
@@ -1442,11 +1443,7 @@ void __generic_unplug_device(request_queue_t *q)
1442 if (!blk_remove_plug(q)) 1443 if (!blk_remove_plug(q))
1443 return; 1444 return;
1444 1445
1445 /* 1446 q->request_fn(q);
1446 * was plugged, fire request_fn if queue has stuff to do
1447 */
1448 if (elv_next_request(q))
1449 q->request_fn(q);
1450} 1447}
1451EXPORT_SYMBOL(__generic_unplug_device); 1448EXPORT_SYMBOL(__generic_unplug_device);
1452 1449
@@ -1776,8 +1773,8 @@ static inline void blk_free_request(request_queue_t *q, struct request *rq)
1776 mempool_free(rq, q->rq.rq_pool); 1773 mempool_free(rq, q->rq.rq_pool);
1777} 1774}
1778 1775
1779static inline struct request *blk_alloc_request(request_queue_t *q, int rw, 1776static inline struct request *
1780 int gfp_mask) 1777blk_alloc_request(request_queue_t *q, int rw, struct bio *bio, int gfp_mask)
1781{ 1778{
1782 struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask); 1779 struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
1783 1780
@@ -1790,7 +1787,7 @@ static inline struct request *blk_alloc_request(request_queue_t *q, int rw,
1790 */ 1787 */
1791 rq->flags = rw; 1788 rq->flags = rw;
1792 1789
1793 if (!elv_set_request(q, rq, gfp_mask)) 1790 if (!elv_set_request(q, rq, bio, gfp_mask))
1794 return rq; 1791 return rq;
1795 1792
1796 mempool_free(rq, q->rq.rq_pool); 1793 mempool_free(rq, q->rq.rq_pool);
@@ -1872,7 +1869,8 @@ static void freed_request(request_queue_t *q, int rw)
1872/* 1869/*
1873 * Get a free request, queue_lock must not be held 1870 * Get a free request, queue_lock must not be held
1874 */ 1871 */
1875static struct request *get_request(request_queue_t *q, int rw, int gfp_mask) 1872static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
1873 int gfp_mask)
1876{ 1874{
1877 struct request *rq = NULL; 1875 struct request *rq = NULL;
1878 struct request_list *rl = &q->rq; 1876 struct request_list *rl = &q->rq;
@@ -1895,7 +1893,7 @@ static struct request *get_request(request_queue_t *q, int rw, int gfp_mask)
1895 } 1893 }
1896 } 1894 }
1897 1895
1898 switch (elv_may_queue(q, rw)) { 1896 switch (elv_may_queue(q, rw, bio)) {
1899 case ELV_MQUEUE_NO: 1897 case ELV_MQUEUE_NO:
1900 goto rq_starved; 1898 goto rq_starved;
1901 case ELV_MQUEUE_MAY: 1899 case ELV_MQUEUE_MAY:
@@ -1920,7 +1918,7 @@ get_rq:
1920 set_queue_congested(q, rw); 1918 set_queue_congested(q, rw);
1921 spin_unlock_irq(q->queue_lock); 1919 spin_unlock_irq(q->queue_lock);
1922 1920
1923 rq = blk_alloc_request(q, rw, gfp_mask); 1921 rq = blk_alloc_request(q, rw, bio, gfp_mask);
1924 if (!rq) { 1922 if (!rq) {
1925 /* 1923 /*
1926 * Allocation failed presumably due to memory. Undo anything 1924 * Allocation failed presumably due to memory. Undo anything
@@ -1961,7 +1959,8 @@ out:
1961 * No available requests for this queue, unplug the device and wait for some 1959 * No available requests for this queue, unplug the device and wait for some
1962 * requests to become available. 1960 * requests to become available.
1963 */ 1961 */
1964static struct request *get_request_wait(request_queue_t *q, int rw) 1962static struct request *get_request_wait(request_queue_t *q, int rw,
1963 struct bio *bio)
1965{ 1964{
1966 DEFINE_WAIT(wait); 1965 DEFINE_WAIT(wait);
1967 struct request *rq; 1966 struct request *rq;
@@ -1972,7 +1971,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw)
1972 prepare_to_wait_exclusive(&rl->wait[rw], &wait, 1971 prepare_to_wait_exclusive(&rl->wait[rw], &wait,
1973 TASK_UNINTERRUPTIBLE); 1972 TASK_UNINTERRUPTIBLE);
1974 1973
1975 rq = get_request(q, rw, GFP_NOIO); 1974 rq = get_request(q, rw, bio, GFP_NOIO);
1976 1975
1977 if (!rq) { 1976 if (!rq) {
1978 struct io_context *ioc; 1977 struct io_context *ioc;
@@ -2003,9 +2002,9 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask)
2003 BUG_ON(rw != READ && rw != WRITE); 2002 BUG_ON(rw != READ && rw != WRITE);
2004 2003
2005 if (gfp_mask & __GFP_WAIT) 2004 if (gfp_mask & __GFP_WAIT)
2006 rq = get_request_wait(q, rw); 2005 rq = get_request_wait(q, rw, NULL);
2007 else 2006 else
2008 rq = get_request(q, rw, gfp_mask); 2007 rq = get_request(q, rw, NULL, gfp_mask);
2009 2008
2010 return rq; 2009 return rq;
2011} 2010}
@@ -2333,7 +2332,6 @@ static void __blk_put_request(request_queue_t *q, struct request *req)
2333 return; 2332 return;
2334 2333
2335 req->rq_status = RQ_INACTIVE; 2334 req->rq_status = RQ_INACTIVE;
2336 req->q = NULL;
2337 req->rl = NULL; 2335 req->rl = NULL;
2338 2336
2339 /* 2337 /*
@@ -2462,6 +2460,8 @@ static int attempt_merge(request_queue_t *q, struct request *req,
2462 req->rq_disk->in_flight--; 2460 req->rq_disk->in_flight--;
2463 } 2461 }
2464 2462
2463 req->ioprio = ioprio_best(req->ioprio, next->ioprio);
2464
2465 __blk_put_request(q, next); 2465 __blk_put_request(q, next);
2466 return 1; 2466 return 1;
2467} 2467}
@@ -2514,11 +2514,13 @@ static int __make_request(request_queue_t *q, struct bio *bio)
2514{ 2514{
2515 struct request *req, *freereq = NULL; 2515 struct request *req, *freereq = NULL;
2516 int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync; 2516 int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync;
2517 unsigned short prio;
2517 sector_t sector; 2518 sector_t sector;
2518 2519
2519 sector = bio->bi_sector; 2520 sector = bio->bi_sector;
2520 nr_sectors = bio_sectors(bio); 2521 nr_sectors = bio_sectors(bio);
2521 cur_nr_sectors = bio_cur_sectors(bio); 2522 cur_nr_sectors = bio_cur_sectors(bio);
2523 prio = bio_prio(bio);
2522 2524
2523 rw = bio_data_dir(bio); 2525 rw = bio_data_dir(bio);
2524 sync = bio_sync(bio); 2526 sync = bio_sync(bio);
@@ -2559,6 +2561,7 @@ again:
2559 req->biotail->bi_next = bio; 2561 req->biotail->bi_next = bio;
2560 req->biotail = bio; 2562 req->biotail = bio;
2561 req->nr_sectors = req->hard_nr_sectors += nr_sectors; 2563 req->nr_sectors = req->hard_nr_sectors += nr_sectors;
2564 req->ioprio = ioprio_best(req->ioprio, prio);
2562 drive_stat_acct(req, nr_sectors, 0); 2565 drive_stat_acct(req, nr_sectors, 0);
2563 if (!attempt_back_merge(q, req)) 2566 if (!attempt_back_merge(q, req))
2564 elv_merged_request(q, req); 2567 elv_merged_request(q, req);
@@ -2583,6 +2586,7 @@ again:
2583 req->hard_cur_sectors = cur_nr_sectors; 2586 req->hard_cur_sectors = cur_nr_sectors;
2584 req->sector = req->hard_sector = sector; 2587 req->sector = req->hard_sector = sector;
2585 req->nr_sectors = req->hard_nr_sectors += nr_sectors; 2588 req->nr_sectors = req->hard_nr_sectors += nr_sectors;
2589 req->ioprio = ioprio_best(req->ioprio, prio);
2586 drive_stat_acct(req, nr_sectors, 0); 2590 drive_stat_acct(req, nr_sectors, 0);
2587 if (!attempt_front_merge(q, req)) 2591 if (!attempt_front_merge(q, req))
2588 elv_merged_request(q, req); 2592 elv_merged_request(q, req);
@@ -2610,7 +2614,7 @@ get_rq:
2610 freereq = NULL; 2614 freereq = NULL;
2611 } else { 2615 } else {
2612 spin_unlock_irq(q->queue_lock); 2616 spin_unlock_irq(q->queue_lock);
2613 if ((freereq = get_request(q, rw, GFP_ATOMIC)) == NULL) { 2617 if ((freereq = get_request(q, rw, bio, GFP_ATOMIC)) == NULL) {
2614 /* 2618 /*
2615 * READA bit set 2619 * READA bit set
2616 */ 2620 */
@@ -2618,7 +2622,7 @@ get_rq:
2618 if (bio_rw_ahead(bio)) 2622 if (bio_rw_ahead(bio))
2619 goto end_io; 2623 goto end_io;
2620 2624
2621 freereq = get_request_wait(q, rw); 2625 freereq = get_request_wait(q, rw, bio);
2622 } 2626 }
2623 goto again; 2627 goto again;
2624 } 2628 }
@@ -2646,6 +2650,7 @@ get_rq:
2646 req->buffer = bio_data(bio); /* see ->buffer comment above */ 2650 req->buffer = bio_data(bio); /* see ->buffer comment above */
2647 req->waiting = NULL; 2651 req->waiting = NULL;
2648 req->bio = req->biotail = bio; 2652 req->bio = req->biotail = bio;
2653 req->ioprio = prio;
2649 req->rq_disk = bio->bi_bdev->bd_disk; 2654 req->rq_disk = bio->bi_bdev->bd_disk;
2650 req->start_time = jiffies; 2655 req->start_time = jiffies;
2651 2656
@@ -2674,7 +2679,7 @@ static inline void blk_partition_remap(struct bio *bio)
2674 if (bdev != bdev->bd_contains) { 2679 if (bdev != bdev->bd_contains) {
2675 struct hd_struct *p = bdev->bd_part; 2680 struct hd_struct *p = bdev->bd_part;
2676 2681
2677 switch (bio->bi_rw) { 2682 switch (bio_data_dir(bio)) {
2678 case READ: 2683 case READ:
2679 p->read_sectors += bio_sectors(bio); 2684 p->read_sectors += bio_sectors(bio);
2680 p->reads++; 2685 p->reads++;
@@ -2693,6 +2698,7 @@ void blk_finish_queue_drain(request_queue_t *q)
2693{ 2698{
2694 struct request_list *rl = &q->rq; 2699 struct request_list *rl = &q->rq;
2695 struct request *rq; 2700 struct request *rq;
2701 int requeued = 0;
2696 2702
2697 spin_lock_irq(q->queue_lock); 2703 spin_lock_irq(q->queue_lock);
2698 clear_bit(QUEUE_FLAG_DRAIN, &q->queue_flags); 2704 clear_bit(QUEUE_FLAG_DRAIN, &q->queue_flags);
@@ -2701,9 +2707,13 @@ void blk_finish_queue_drain(request_queue_t *q)
2701 rq = list_entry_rq(q->drain_list.next); 2707 rq = list_entry_rq(q->drain_list.next);
2702 2708
2703 list_del_init(&rq->queuelist); 2709 list_del_init(&rq->queuelist);
2704 __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1); 2710 elv_requeue_request(q, rq);
2711 requeued++;
2705 } 2712 }
2706 2713
2714 if (requeued)
2715 q->request_fn(q);
2716
2707 spin_unlock_irq(q->queue_lock); 2717 spin_unlock_irq(q->queue_lock);
2708 2718
2709 wake_up(&rl->wait[0]); 2719 wake_up(&rl->wait[0]);
@@ -2900,7 +2910,7 @@ void submit_bio(int rw, struct bio *bio)
2900 2910
2901 BIO_BUG_ON(!bio->bi_size); 2911 BIO_BUG_ON(!bio->bi_size);
2902 BIO_BUG_ON(!bio->bi_io_vec); 2912 BIO_BUG_ON(!bio->bi_io_vec);
2903 bio->bi_rw = rw; 2913 bio->bi_rw |= rw;
2904 if (rw & WRITE) 2914 if (rw & WRITE)
2905 mod_page_state(pgpgout, count); 2915 mod_page_state(pgpgout, count);
2906 else 2916 else
@@ -3257,8 +3267,11 @@ void exit_io_context(void)
3257 struct io_context *ioc; 3267 struct io_context *ioc;
3258 3268
3259 local_irq_save(flags); 3269 local_irq_save(flags);
3270 task_lock(current);
3260 ioc = current->io_context; 3271 ioc = current->io_context;
3261 current->io_context = NULL; 3272 current->io_context = NULL;
3273 ioc->task = NULL;
3274 task_unlock(current);
3262 local_irq_restore(flags); 3275 local_irq_restore(flags);
3263 3276
3264 if (ioc->aic && ioc->aic->exit) 3277 if (ioc->aic && ioc->aic->exit)
@@ -3293,12 +3306,12 @@ struct io_context *get_io_context(int gfp_flags)
3293 ret = kmem_cache_alloc(iocontext_cachep, gfp_flags); 3306 ret = kmem_cache_alloc(iocontext_cachep, gfp_flags);
3294 if (ret) { 3307 if (ret) {
3295 atomic_set(&ret->refcount, 1); 3308 atomic_set(&ret->refcount, 1);
3296 ret->pid = tsk->pid; 3309 ret->task = current;
3310 ret->set_ioprio = NULL;
3297 ret->last_waited = jiffies; /* doesn't matter... */ 3311 ret->last_waited = jiffies; /* doesn't matter... */
3298 ret->nr_batch_requests = 0; /* because this is 0 */ 3312 ret->nr_batch_requests = 0; /* because this is 0 */
3299 ret->aic = NULL; 3313 ret->aic = NULL;
3300 ret->cic = NULL; 3314 ret->cic = NULL;
3301 spin_lock_init(&ret->lock);
3302 3315
3303 local_irq_save(flags); 3316 local_irq_save(flags);
3304 3317