diff options
author | Jens Axboe <jaxboe@fusionio.com> | 2011-08-19 02:34:48 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2011-08-19 02:34:48 -0400 |
commit | b53d1ed734a2b9af8da115b836b658daa7d47a48 (patch) | |
tree | 07ed12caa6fd50f97568f419448cf03906d980c4 /block | |
parent | 4853abaae7e4a2af938115ce9071ef8684fb7af4 (diff) |
Revert "cfq: Remove special treatment for metadata rqs."
We have a kernel build regression since 3.1-rc1, which is about 10%
regression. The kernel source is in an ext3 filesystem.
Alex Shi bisect it to commit:
commit a07405b7802691d29ab3b23bdc76ee6d006aad0b
Author: Justin TerAvest <teravest@google.com>
Date: Sun Jul 10 22:09:19 2011 +0200
cfq: Remove special treatment for metadata rqs.
Apparently this is caused by lack metadata preemption, where ext3/ext4
do use READ_META. I didn't see a way to fix the issue, so suggest
reverting the patch.
This reverts commit a07405b7802691d29ab3b23bdc76ee6d006aad0b.
Reported-by: Alex Shi<alex.shi@intel.com>
Reported-by: Shaohua Li<shaohua.li@intel.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'block')
-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); |