diff options
| -rw-r--r-- | block/cfq-iosched.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 650834537606..a33bd4377c61 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
| @@ -130,6 +130,8 @@ struct cfq_queue { | |||
| 130 | unsigned long slice_end; | 130 | unsigned long slice_end; |
| 131 | long slice_resid; | 131 | long slice_resid; |
| 132 | 132 | ||
| 133 | /* pending metadata requests */ | ||
| 134 | int meta_pending; | ||
| 133 | /* number of requests that are on the dispatch list or inside driver */ | 135 | /* number of requests that are on the dispatch list or inside driver */ |
| 134 | int dispatched; | 136 | int dispatched; |
| 135 | 137 | ||
| @@ -682,6 +684,9 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2, | |||
| 682 | if (rq_is_sync(rq1) != rq_is_sync(rq2)) | 684 | if (rq_is_sync(rq1) != rq_is_sync(rq2)) |
| 683 | return rq_is_sync(rq1) ? rq1 : rq2; | 685 | return rq_is_sync(rq1) ? rq1 : rq2; |
| 684 | 686 | ||
| 687 | if ((rq1->cmd_flags ^ rq2->cmd_flags) & REQ_META) | ||
| 688 | return rq1->cmd_flags & REQ_META ? rq1 : rq2; | ||
| 689 | |||
| 685 | s1 = blk_rq_pos(rq1); | 690 | s1 = blk_rq_pos(rq1); |
| 686 | s2 = blk_rq_pos(rq2); | 691 | s2 = blk_rq_pos(rq2); |
| 687 | 692 | ||
| @@ -1607,6 +1612,10 @@ static void cfq_remove_request(struct request *rq) | |||
| 1607 | cfqq->cfqd->rq_queued--; | 1612 | cfqq->cfqd->rq_queued--; |
| 1608 | cfq_blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg, | 1613 | cfq_blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg, |
| 1609 | rq_data_dir(rq), rq_is_sync(rq)); | 1614 | rq_data_dir(rq), rq_is_sync(rq)); |
| 1615 | if (rq->cmd_flags & REQ_META) { | ||
| 1616 | WARN_ON(!cfqq->meta_pending); | ||
| 1617 | cfqq->meta_pending--; | ||
| 1618 | } | ||
| 1610 | } | 1619 | } |
| 1611 | 1620 | ||
| 1612 | static int cfq_merge(struct request_queue *q, struct request **req, | 1621 | static int cfq_merge(struct request_queue *q, struct request **req, |
| @@ -3360,6 +3369,13 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, | |||
| 3360 | return true; | 3369 | return true; |
| 3361 | 3370 | ||
| 3362 | /* | 3371 | /* |
| 3372 | * So both queues are sync. Let the new request get disk time if | ||
| 3373 | * it's a metadata request and the current queue is doing regular IO. | ||
| 3374 | */ | ||
| 3375 | if ((rq->cmd_flags & REQ_META) && !cfqq->meta_pending) | ||
| 3376 | return true; | ||
| 3377 | |||
| 3378 | /* | ||
| 3363 | * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice. | 3379 | * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice. |
| 3364 | */ | 3380 | */ |
| 3365 | if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) | 3381 | if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) |
| @@ -3423,6 +3439,8 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
| 3423 | struct cfq_io_context *cic = RQ_CIC(rq); | 3439 | struct cfq_io_context *cic = RQ_CIC(rq); |
| 3424 | 3440 | ||
| 3425 | cfqd->rq_queued++; | 3441 | cfqd->rq_queued++; |
| 3442 | if (rq->cmd_flags & REQ_META) | ||
| 3443 | cfqq->meta_pending++; | ||
| 3426 | 3444 | ||
| 3427 | cfq_update_io_thinktime(cfqd, cfqq, cic); | 3445 | cfq_update_io_thinktime(cfqd, cfqq, cic); |
| 3428 | cfq_update_io_seektime(cfqd, cfqq, rq); | 3446 | cfq_update_io_seektime(cfqd, cfqq, rq); |
