diff options
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r-- | block/cfq-iosched.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 8b5ba184cf91..13b612f9f27a 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -253,6 +253,7 @@ enum cfqq_state_flags { | |||
253 | CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */ | 253 | CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */ |
254 | CFQ_CFQQ_FLAG_sync, /* synchronous queue */ | 254 | CFQ_CFQQ_FLAG_sync, /* synchronous queue */ |
255 | CFQ_CFQQ_FLAG_coop, /* cfqq is shared */ | 255 | CFQ_CFQQ_FLAG_coop, /* cfqq is shared */ |
256 | CFQ_CFQQ_FLAG_coop_preempt, /* coop preempt */ | ||
256 | }; | 257 | }; |
257 | 258 | ||
258 | #define CFQ_CFQQ_FNS(name) \ | 259 | #define CFQ_CFQQ_FNS(name) \ |
@@ -279,6 +280,7 @@ CFQ_CFQQ_FNS(prio_changed); | |||
279 | CFQ_CFQQ_FNS(slice_new); | 280 | CFQ_CFQQ_FNS(slice_new); |
280 | CFQ_CFQQ_FNS(sync); | 281 | CFQ_CFQQ_FNS(sync); |
281 | CFQ_CFQQ_FNS(coop); | 282 | CFQ_CFQQ_FNS(coop); |
283 | CFQ_CFQQ_FNS(coop_preempt); | ||
282 | #undef CFQ_CFQQ_FNS | 284 | #undef CFQ_CFQQ_FNS |
283 | 285 | ||
284 | #define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \ | 286 | #define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \ |
@@ -1068,9 +1070,16 @@ static struct cfq_queue *cfq_get_next_queue(struct cfq_data *cfqd) | |||
1068 | static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd, | 1070 | static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd, |
1069 | struct cfq_queue *cfqq) | 1071 | struct cfq_queue *cfqq) |
1070 | { | 1072 | { |
1071 | if (!cfqq) | 1073 | if (!cfqq) { |
1072 | cfqq = cfq_get_next_queue(cfqd); | 1074 | cfqq = cfq_get_next_queue(cfqd); |
1073 | 1075 | ||
1076 | if (cfqq && !cfq_cfqq_coop_preempt(cfqq)) | ||
1077 | cfq_clear_cfqq_coop(cfqq); | ||
1078 | } | ||
1079 | |||
1080 | if (cfqq) | ||
1081 | cfq_clear_cfqq_coop_preempt(cfqq); | ||
1082 | |||
1074 | __cfq_set_active_queue(cfqd, cfqq); | 1083 | __cfq_set_active_queue(cfqd, cfqq); |
1075 | return cfqq; | 1084 | return cfqq; |
1076 | } | 1085 | } |
@@ -2409,7 +2418,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, | |||
2409 | * it's a metadata request and the current queue is doing regular IO. | 2418 | * it's a metadata request and the current queue is doing regular IO. |
2410 | */ | 2419 | */ |
2411 | if (rq_is_meta(rq) && !cfqq->meta_pending) | 2420 | if (rq_is_meta(rq) && !cfqq->meta_pending) |
2412 | return false; | 2421 | return true; |
2413 | 2422 | ||
2414 | /* | 2423 | /* |
2415 | * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice. | 2424 | * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice. |
@@ -2425,7 +2434,16 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, | |||
2425 | * current cfqq, let it preempt | 2434 | * current cfqq, let it preempt |
2426 | */ | 2435 | */ |
2427 | if (cfq_rq_close(cfqd, cfqq, rq)) | 2436 | if (cfq_rq_close(cfqd, cfqq, rq)) |
2437 | if (cfq_rq_close(cfqd, cfqq, rq) && (!cfq_cfqq_coop(new_cfqq) || | ||
2438 | cfqd->busy_queues == 1)) { | ||
2439 | /* | ||
2440 | * Mark new queue coop_preempt, so its coop flag will not be | ||
2441 | * cleared when new queue gets scheduled at the very first time | ||
2442 | */ | ||
2443 | cfq_mark_cfqq_coop_preempt(new_cfqq); | ||
2444 | cfq_mark_cfqq_coop(new_cfqq); | ||
2428 | return true; | 2445 | return true; |
2446 | } | ||
2429 | 2447 | ||
2430 | return false; | 2448 | return false; |
2431 | } | 2449 | } |