diff options
| -rw-r--r-- | block/cfq-iosched.c | 17 |
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); | |||
| 222 | CFQ_CFQQ_FNS(slice_new); | 223 | CFQ_CFQQ_FNS(slice_new); |
| 223 | CFQ_CFQQ_FNS(sync); | 224 | CFQ_CFQQ_FNS(sync); |
| 224 | CFQ_CFQQ_FNS(coop); | 225 | CFQ_CFQQ_FNS(coop); |
| 226 | CFQ_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 | } |
