Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 242248
b: refs/heads/master
c: ef8a41d
h: refs/heads/master
v: v3
  • Loading branch information
Shaohua Li authored and Jens Axboe committed Mar 7, 2011
1 parent 61a8abe commit 4009142
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 93803e0140c6216b68fe926ccc611297120da273
refs/heads/master: ef8a41df8c140f10108de75b01b6369d6e49113c
26 changes: 24 additions & 2 deletions trunk/block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ struct cfq_data {
struct rb_root prio_trees[CFQ_PRIO_LISTS];

unsigned int busy_queues;
unsigned int busy_sync_queues;

int rq_in_driver;
int rq_in_flight[2];
Expand Down Expand Up @@ -1344,6 +1345,8 @@ static void cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
BUG_ON(cfq_cfqq_on_rr(cfqq));
cfq_mark_cfqq_on_rr(cfqq);
cfqd->busy_queues++;
if (cfq_cfqq_sync(cfqq))
cfqd->busy_sync_queues++;

cfq_resort_rr_list(cfqd, cfqq);
}
Expand All @@ -1370,6 +1373,8 @@ static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
cfq_group_service_tree_del(cfqd, cfqq->cfqg);
BUG_ON(!cfqd->busy_queues);
cfqd->busy_queues--;
if (cfq_cfqq_sync(cfqq))
cfqd->busy_sync_queues--;
}

/*
Expand Down Expand Up @@ -2377,22 +2382,39 @@ static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
* Does this cfqq already have too much IO in flight?
*/
if (cfqq->dispatched >= max_dispatch) {
bool promote_sync = false;
/*
* idle queue must always only have a single IO in flight
*/
if (cfq_class_idle(cfqq))
return false;

/*
* If there is only one sync queue, and its think time is
* small, we can ignore async queue here and give the sync
* queue no dispatch limit. The reason is a sync queue can
* preempt async queue, limiting the sync queue doesn't make
* sense. This is useful for aiostress test.
*/
if (cfq_cfqq_sync(cfqq) && cfqd->busy_sync_queues == 1) {
struct cfq_io_context *cic = RQ_CIC(cfqq->next_rq);

if (sample_valid(cic->ttime_samples) &&
cic->ttime_mean < cfqd->cfq_slice_idle)
promote_sync = true;
}

/*
* We have other queues, don't allow more IO from this one
*/
if (cfqd->busy_queues > 1 && cfq_slice_used_soon(cfqd, cfqq))
if (cfqd->busy_queues > 1 && cfq_slice_used_soon(cfqd, cfqq) &&
!promote_sync)
return false;

/*
* Sole queue user, no limit
*/
if (cfqd->busy_queues == 1)
if (cfqd->busy_queues == 1 || promote_sync)
max_dispatch = -1;
else
/*
Expand Down

0 comments on commit 4009142

Please sign in to comment.