aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/cfq-iosched.c36
-rw-r--r--include/linux/blkdev.h3
2 files changed, 28 insertions, 11 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 62defd05518f..d5927b53020e 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -55,6 +55,7 @@ static const int cfq_hist_divisor = 4;
55#define RQ_CIC(rq) \ 55#define RQ_CIC(rq) \
56 ((struct cfq_io_context *) (rq)->elevator_private) 56 ((struct cfq_io_context *) (rq)->elevator_private)
57#define RQ_CFQQ(rq) (struct cfq_queue *) ((rq)->elevator_private2) 57#define RQ_CFQQ(rq) (struct cfq_queue *) ((rq)->elevator_private2)
58#define RQ_CFQG(rq) (struct cfq_group *) ((rq)->elevator_private3)
58 59
59static struct kmem_cache *cfq_pool; 60static struct kmem_cache *cfq_pool;
60static struct kmem_cache *cfq_ioc_pool; 61static struct kmem_cache *cfq_ioc_pool;
@@ -1001,6 +1002,12 @@ static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create)
1001 return cfqg; 1002 return cfqg;
1002} 1003}
1003 1004
1005static inline struct cfq_group *cfq_ref_get_cfqg(struct cfq_group *cfqg)
1006{
1007 atomic_inc(&cfqg->ref);
1008 return cfqg;
1009}
1010
1004static void cfq_link_cfqq_cfqg(struct cfq_queue *cfqq, struct cfq_group *cfqg) 1011static void cfq_link_cfqq_cfqg(struct cfq_queue *cfqq, struct cfq_group *cfqg)
1005{ 1012{
1006 /* Currently, all async queues are mapped to root group */ 1013 /* Currently, all async queues are mapped to root group */
@@ -1084,6 +1091,12 @@ static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create)
1084{ 1091{
1085 return &cfqd->root_group; 1092 return &cfqd->root_group;
1086} 1093}
1094
1095static inline struct cfq_group *cfq_ref_get_cfqg(struct cfq_group *cfqg)
1096{
1097 return NULL;
1098}
1099
1087static inline void 1100static inline void
1088cfq_link_cfqq_cfqg(struct cfq_queue *cfqq, struct cfq_group *cfqg) { 1101cfq_link_cfqq_cfqg(struct cfq_queue *cfqq, struct cfq_group *cfqg) {
1089 cfqq->cfqg = cfqg; 1102 cfqq->cfqg = cfqg;
@@ -1386,12 +1399,12 @@ static void cfq_reposition_rq_rb(struct cfq_queue *cfqq, struct request *rq)
1386{ 1399{
1387 elv_rb_del(&cfqq->sort_list, rq); 1400 elv_rb_del(&cfqq->sort_list, rq);
1388 cfqq->queued[rq_is_sync(rq)]--; 1401 cfqq->queued[rq_is_sync(rq)]--;
1389 blkiocg_update_io_remove_stats(&cfqq->cfqg->blkg, rq_data_dir(rq), 1402 blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg, rq_data_dir(rq),
1390 rq_is_sync(rq)); 1403 rq_is_sync(rq));
1391 cfq_add_rq_rb(rq); 1404 cfq_add_rq_rb(rq);
1392 blkiocg_update_io_add_stats( 1405 blkiocg_update_io_add_stats(&(RQ_CFQG(rq))->blkg,
1393 &cfqq->cfqg->blkg, &cfqq->cfqd->serving_group->blkg, 1406 &cfqq->cfqd->serving_group->blkg, rq_data_dir(rq),
1394 rq_data_dir(rq), rq_is_sync(rq)); 1407 rq_is_sync(rq));
1395} 1408}
1396 1409
1397static struct request * 1410static struct request *
@@ -1447,7 +1460,7 @@ static void cfq_remove_request(struct request *rq)
1447 cfq_del_rq_rb(rq); 1460 cfq_del_rq_rb(rq);
1448 1461
1449 cfqq->cfqd->rq_queued--; 1462 cfqq->cfqd->rq_queued--;
1450 blkiocg_update_io_remove_stats(&cfqq->cfqg->blkg, rq_data_dir(rq), 1463 blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg, rq_data_dir(rq),
1451 rq_is_sync(rq)); 1464 rq_is_sync(rq));
1452 if (rq_is_meta(rq)) { 1465 if (rq_is_meta(rq)) {
1453 WARN_ON(!cfqq->meta_pending); 1466 WARN_ON(!cfqq->meta_pending);
@@ -1483,8 +1496,7 @@ static void cfq_merged_request(struct request_queue *q, struct request *req,
1483static void cfq_bio_merged(struct request_queue *q, struct request *req, 1496static void cfq_bio_merged(struct request_queue *q, struct request *req,
1484 struct bio *bio) 1497 struct bio *bio)
1485{ 1498{
1486 struct cfq_queue *cfqq = RQ_CFQQ(req); 1499 blkiocg_update_io_merged_stats(&(RQ_CFQG(req))->blkg, bio_data_dir(bio),
1487 blkiocg_update_io_merged_stats(&cfqq->cfqg->blkg, bio_data_dir(bio),
1488 cfq_bio_sync(bio)); 1500 cfq_bio_sync(bio));
1489} 1501}
1490 1502
@@ -1505,7 +1517,7 @@ cfq_merged_requests(struct request_queue *q, struct request *rq,
1505 if (cfqq->next_rq == next) 1517 if (cfqq->next_rq == next)
1506 cfqq->next_rq = rq; 1518 cfqq->next_rq = rq;
1507 cfq_remove_request(next); 1519 cfq_remove_request(next);
1508 blkiocg_update_io_merged_stats(&cfqq->cfqg->blkg, rq_data_dir(next), 1520 blkiocg_update_io_merged_stats(&(RQ_CFQG(rq))->blkg, rq_data_dir(next),
1509 rq_is_sync(next)); 1521 rq_is_sync(next));
1510} 1522}
1511 1523
@@ -3240,8 +3252,7 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq)
3240 rq_set_fifo_time(rq, jiffies + cfqd->cfq_fifo_expire[rq_is_sync(rq)]); 3252 rq_set_fifo_time(rq, jiffies + cfqd->cfq_fifo_expire[rq_is_sync(rq)]);
3241 list_add_tail(&rq->queuelist, &cfqq->fifo); 3253 list_add_tail(&rq->queuelist, &cfqq->fifo);
3242 cfq_add_rq_rb(rq); 3254 cfq_add_rq_rb(rq);
3243 3255 blkiocg_update_io_add_stats(&(RQ_CFQG(rq))->blkg,
3244 blkiocg_update_io_add_stats(&cfqq->cfqg->blkg,
3245 &cfqd->serving_group->blkg, rq_data_dir(rq), 3256 &cfqd->serving_group->blkg, rq_data_dir(rq),
3246 rq_is_sync(rq)); 3257 rq_is_sync(rq));
3247 cfq_rq_enqueued(cfqd, cfqq, rq); 3258 cfq_rq_enqueued(cfqd, cfqq, rq);
@@ -3472,6 +3483,10 @@ static void cfq_put_request(struct request *rq)
3472 rq->elevator_private = NULL; 3483 rq->elevator_private = NULL;
3473 rq->elevator_private2 = NULL; 3484 rq->elevator_private2 = NULL;
3474 3485
3486 /* Put down rq reference on cfqg */
3487 cfq_put_cfqg(RQ_CFQG(rq));
3488 rq->elevator_private3 = NULL;
3489
3475 cfq_put_queue(cfqq); 3490 cfq_put_queue(cfqq);
3476 } 3491 }
3477} 3492}
@@ -3560,6 +3575,7 @@ new_queue:
3560 3575
3561 rq->elevator_private = cic; 3576 rq->elevator_private = cic;
3562 rq->elevator_private2 = cfqq; 3577 rq->elevator_private2 = cfqq;
3578 rq->elevator_private3 = cfq_ref_get_cfqg(cfqq->cfqg);
3563 return 0; 3579 return 0;
3564 3580
3565queue_fail: 3581queue_fail:
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index d483c494672a..5cf17a49ce38 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -186,11 +186,12 @@ struct request {
186 }; 186 };
187 187
188 /* 188 /*
189 * two pointers are available for the IO schedulers, if they need 189 * Three pointers are available for the IO schedulers, if they need
190 * more they have to dynamically allocate it. 190 * more they have to dynamically allocate it.
191 */ 191 */
192 void *elevator_private; 192 void *elevator_private;
193 void *elevator_private2; 193 void *elevator_private2;
194 void *elevator_private3;
194 195
195 struct gendisk *rq_disk; 196 struct gendisk *rq_disk;
196 unsigned long start_time; 197 unsigned long start_time;