diff options
-rw-r--r-- | block/cfq-iosched.c | 34 |
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 | |||
1167 | static 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 | |||
1163 | static void cfq_arm_slice_timer(struct cfq_data *cfqd) | 1191 | static 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 | /* |