aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2006-07-22 19:42:19 -0400
committerJens Axboe <axboe@nelson.home.kernel.dk>2006-09-30 14:29:43 -0400
commit374f84ac39ec7829a57a66efd5125d3561ff0e00 (patch)
treea1303aba1804f621ebea8304ba94e02c16a70a5c /block/cfq-iosched.c
parentcaa38fb0f481a3cb732b115cb59bfa6b59b6daaf (diff)
[PATCH] cfq-iosched: use metadata read flag
Give meta data reads preference over regular reads, as the process often needs to get that out of the way to do the io it was actually interested in. Signed-off-by: Jens Axboe <axboe@suse.de>
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r--block/cfq-iosched.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 141104835952..6dbee46240c5 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -141,6 +141,8 @@ struct cfq_queue {
141 int queued[2]; 141 int queued[2];
142 /* currently allocated requests */ 142 /* currently allocated requests */
143 int allocated[2]; 143 int allocated[2];
144 /* pending metadata requests */
145 int meta_pending;
144 /* fifo list of requests in sort_list */ 146 /* fifo list of requests in sort_list */
145 struct list_head fifo; 147 struct list_head fifo;
146 148
@@ -248,6 +250,10 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2)
248 return rq1; 250 return rq1;
249 else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) 251 else if (rq_is_sync(rq2) && !rq_is_sync(rq1))
250 return rq2; 252 return rq2;
253 if (rq_is_meta(rq1) && !rq_is_meta(rq2))
254 return rq1;
255 else if (rq_is_meta(rq2) && !rq_is_meta(rq1))
256 return rq2;
251 257
252 s1 = rq1->sector; 258 s1 = rq1->sector;
253 s2 = rq2->sector; 259 s2 = rq2->sector;
@@ -510,6 +516,11 @@ static void cfq_remove_request(struct request *rq)
510 516
511 list_del_init(&rq->queuelist); 517 list_del_init(&rq->queuelist);
512 cfq_del_rq_rb(rq); 518 cfq_del_rq_rb(rq);
519
520 if (rq_is_meta(rq)) {
521 WARN_ON(!cfqq->meta_pending);
522 cfqq->meta_pending--;
523 }
513} 524}
514 525
515static int 526static int
@@ -1527,8 +1538,18 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
1527 */ 1538 */
1528 if (new_cfqq->slice_left < cfqd->cfq_slice_idle) 1539 if (new_cfqq->slice_left < cfqd->cfq_slice_idle)
1529 return 0; 1540 return 0;
1541 /*
1542 * if the new request is sync, but the currently running queue is
1543 * not, let the sync request have priority.
1544 */
1530 if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq)) 1545 if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq))
1531 return 1; 1546 return 1;
1547 /*
1548 * So both queues are sync. Let the new request get disk time if
1549 * it's a metadata request and the current queue is doing regular IO.
1550 */
1551 if (rq_is_meta(rq) && !cfqq->meta_pending)
1552 return 1;
1532 1553
1533 return 0; 1554 return 0;
1534} 1555}
@@ -1564,6 +1585,9 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1564{ 1585{
1565 struct cfq_io_context *cic = RQ_CIC(rq); 1586 struct cfq_io_context *cic = RQ_CIC(rq);
1566 1587
1588 if (rq_is_meta(rq))
1589 cfqq->meta_pending++;
1590
1567 /* 1591 /*
1568 * check if this request is a better next-serve candidate)) { 1592 * check if this request is a better next-serve candidate)) {
1569 */ 1593 */