aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r--block/cfq-iosched.c22
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);
279CFQ_CFQQ_FNS(slice_new); 280CFQ_CFQQ_FNS(slice_new);
280CFQ_CFQQ_FNS(sync); 281CFQ_CFQQ_FNS(sync);
281CFQ_CFQQ_FNS(coop); 282CFQ_CFQQ_FNS(coop);
283CFQ_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)
1068static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd, 1070static 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}