summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/cfq-iosched.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 8917f2b3a783..70b48ea0e3e9 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -181,6 +181,8 @@ struct cfq_data {
* Fallback dummy cfqq for extreme OOM conditions
*/
struct cfq_queue oom_cfqq;
+
+ unsigned long last_end_sync_rq;
};
enum cfqq_state_flags {
@@ -1314,6 +1316,8 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
* Does this cfqq already have too much IO in flight?
*/
if (cfqq->dispatched >= max_dispatch) {
+ unsigned long load_at = cfqd->last_end_sync_rq + cfq_slice_sync;
+
/*
* idle queue must always only have a single IO in flight
*/
@@ -1327,6 +1331,14 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
return 0;
/*
+ * If a sync request has completed recently, don't overload
+ * the dispatch queue yet with async requests.
+ */
+ if (cfqd->cfq_desktop && !cfq_cfqq_sync(cfqq)
+ && time_before(jiffies, load_at))
+ return 0;
+
+ /*
* we are the only queue, allow up to 4 times of 'quantum'
*/
if (cfqq->dispatched >= 4 * max_dispatch)
@@ -2158,8 +2170,10 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
if (cfq_cfqq_sync(cfqq))
cfqd->sync_flight--;
- if (sync)
+ if (sync) {
RQ_CIC(rq)->last_end_request = now;
+ cfqd->last_end_sync_rq = now;
+ }
/*
* If this is the active queue, check if it needs to be expired,
@@ -2483,7 +2497,7 @@ static void *cfq_init_queue(struct request_queue *q)
cfqd->cfq_slice_idle = cfq_slice_idle;
cfqd->cfq_desktop = 1;
cfqd->hw_tag = 1;
-
+ cfqd->last_end_sync_rq = jiffies;
return cfqd;
}