aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
diff options
context:
space:
mode:
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 */