aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/cfq-iosched.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 6e5c3d715ebe..76afa3696894 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1160,6 +1160,34 @@ static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd,
1160 return cfqq; 1160 return cfqq;
1161} 1161}
1162 1162
1163/*
1164 * Determine whether we should enforce idle window for this queue.
1165 */
1166
1167static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1168{
1169 enum wl_prio_t prio = cfqq_prio(cfqq);
1170 struct cfq_rb_root *service_tree;
1171
1172 /* We never do for idle class queues. */
1173 if (prio == IDLE_WORKLOAD)
1174 return false;
1175
1176 /* We do for queues that were marked with idle window flag. */
1177 if (cfq_cfqq_idle_window(cfqq))
1178 return true;
1179
1180 /*
1181 * Otherwise, we do only if they are the last ones
1182 * in their service tree.
1183 */
1184 service_tree = service_tree_for(prio, cfqd);
1185 if (service_tree->count == 0)
1186 return true;
1187
1188 return (service_tree->count == 1 && cfq_rb_first(service_tree) == cfqq);
1189}
1190
1163static void cfq_arm_slice_timer(struct cfq_data *cfqd) 1191static void cfq_arm_slice_timer(struct cfq_data *cfqd)
1164{ 1192{
1165 struct cfq_queue *cfqq = cfqd->active_queue; 1193 struct cfq_queue *cfqq = cfqd->active_queue;
@@ -1180,7 +1208,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
1180 /* 1208 /*
1181 * idle is disabled, either manually or by past process history 1209 * idle is disabled, either manually or by past process history
1182 */ 1210 */
1183 if (!cfqd->cfq_slice_idle || !cfq_cfqq_idle_window(cfqq)) 1211 if (!cfqd->cfq_slice_idle || !cfq_should_idle(cfqd, cfqq))
1184 return; 1212 return;
1185 1213
1186 /* 1214 /*
@@ -1362,7 +1390,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
1362 * conditions to happen (or time out) before selecting a new queue. 1390 * conditions to happen (or time out) before selecting a new queue.
1363 */ 1391 */
1364 if (timer_pending(&cfqd->idle_slice_timer) || 1392 if (timer_pending(&cfqd->idle_slice_timer) ||
1365 (cfqq->dispatched && cfq_cfqq_idle_window(cfqq))) { 1393 (cfqq->dispatched && cfq_should_idle(cfqd, cfqq))) {
1366 cfqq = NULL; 1394 cfqq = NULL;
1367 goto keep_queue; 1395 goto keep_queue;
1368 } 1396 }
@@ -1427,7 +1455,7 @@ static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1427 /* 1455 /*
1428 * Drain async requests before we start sync IO 1456 * Drain async requests before we start sync IO
1429 */ 1457 */
1430 if (cfq_cfqq_idle_window(cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC]) 1458 if (cfq_should_idle(cfqd, cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC])
1431 return false; 1459 return false;
1432 1460
1433 /* 1461 /*