aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/cfq-iosched.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 5802e322b7ad..aa1e9535e358 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -196,6 +196,7 @@ enum cfqq_state_flags {
196 CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */ 196 CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */
197 CFQ_CFQQ_FLAG_sync, /* synchronous queue */ 197 CFQ_CFQQ_FLAG_sync, /* synchronous queue */
198 CFQ_CFQQ_FLAG_coop, /* has done a coop jump of the queue */ 198 CFQ_CFQQ_FLAG_coop, /* has done a coop jump of the queue */
199 CFQ_CFQQ_FLAG_coop_preempt, /* coop preempt */
199}; 200};
200 201
201#define CFQ_CFQQ_FNS(name) \ 202#define CFQ_CFQQ_FNS(name) \
@@ -222,6 +223,7 @@ CFQ_CFQQ_FNS(prio_changed);
222CFQ_CFQQ_FNS(slice_new); 223CFQ_CFQQ_FNS(slice_new);
223CFQ_CFQQ_FNS(sync); 224CFQ_CFQQ_FNS(sync);
224CFQ_CFQQ_FNS(coop); 225CFQ_CFQQ_FNS(coop);
226CFQ_CFQQ_FNS(coop_preempt);
225#undef CFQ_CFQQ_FNS 227#undef CFQ_CFQQ_FNS
226 228
227#define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \ 229#define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \
@@ -945,10 +947,13 @@ static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd,
945{ 947{
946 if (!cfqq) { 948 if (!cfqq) {
947 cfqq = cfq_get_next_queue(cfqd); 949 cfqq = cfq_get_next_queue(cfqd);
948 if (cfqq) 950 if (cfqq && !cfq_cfqq_coop_preempt(cfqq))
949 cfq_clear_cfqq_coop(cfqq); 951 cfq_clear_cfqq_coop(cfqq);
950 } 952 }
951 953
954 if (cfqq)
955 cfq_clear_cfqq_coop_preempt(cfqq);
956
952 __cfq_set_active_queue(cfqd, cfqq); 957 __cfq_set_active_queue(cfqd, cfqq);
953 return cfqq; 958 return cfqq;
954} 959}
@@ -2066,8 +2071,16 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
2066 * if this request is as-good as one we would expect from the 2071 * if this request is as-good as one we would expect from the
2067 * current cfqq, let it preempt 2072 * current cfqq, let it preempt
2068 */ 2073 */
2069 if (cfq_rq_close(cfqd, rq)) 2074 if (cfq_rq_close(cfqd, rq) && (!cfq_cfqq_coop(new_cfqq) ||
2075 cfqd->busy_queues == 1)) {
2076 /*
2077 * Mark new queue coop_preempt, so its coop flag will not be
2078 * cleared when new queue gets scheduled at the very first time
2079 */
2080 cfq_mark_cfqq_coop_preempt(new_cfqq);
2081 cfq_mark_cfqq_coop(new_cfqq);
2070 return true; 2082 return true;
2083 }
2071 2084
2072 return false; 2085 return false;
2073} 2086}