Skip to content

Commit b53d1ed

Browse files
author
Jens Axboe
committed
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 a07405b Author: Justin TerAvest <[email protected]> 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 a07405b. Reported-by: Alex Shi<[email protected]> Reported-by: Shaohua Li<[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 4853aba commit b53d1ed

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

block/cfq-iosched.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ struct cfq_queue {
130130
unsigned long slice_end;
131131
long slice_resid;
132132

133+
/* pending metadata requests */
134+
int meta_pending;
133135
/* number of requests that are on the dispatch list or inside driver */
134136
int dispatched;
135137

@@ -682,6 +684,9 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2,
682684
if (rq_is_sync(rq1) != rq_is_sync(rq2))
683685
return rq_is_sync(rq1) ? rq1 : rq2;
684686

687+
if ((rq1->cmd_flags ^ rq2->cmd_flags) & REQ_META)
688+
return rq1->cmd_flags & REQ_META ? rq1 : rq2;
689+
685690
s1 = blk_rq_pos(rq1);
686691
s2 = blk_rq_pos(rq2);
687692

@@ -1607,6 +1612,10 @@ static void cfq_remove_request(struct request *rq)
16071612
cfqq->cfqd->rq_queued--;
16081613
cfq_blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg,
16091614
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+
}
16101619
}
16111620

16121621
static int cfq_merge(struct request_queue *q, struct request **req,
@@ -3359,6 +3368,13 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
33593368
RB_EMPTY_ROOT(&cfqq->sort_list))
33603369
return true;
33613370

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+
33623378
/*
33633379
* Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice.
33643380
*/
@@ -3423,6 +3439,8 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
34233439
struct cfq_io_context *cic = RQ_CIC(rq);
34243440

34253441
cfqd->rq_queued++;
3442+
if (rq->cmd_flags & REQ_META)
3443+
cfqq->meta_pending++;
34263444

34273445
cfq_update_io_thinktime(cfqd, cfqq, cic);
34283446
cfq_update_io_seektime(cfqd, cfqq, rq);

0 commit comments

Comments
 (0)