diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/cfq-iosched.c | 24 |
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 | ||
515 | static int | 526 | static 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 | */ |