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.c70
1 files changed, 49 insertions, 21 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index fab2be0fa215..7f5646ac9f5d 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -393,7 +393,7 @@ static int cfq_queue_empty(struct request_queue *q)
393{ 393{
394 struct cfq_data *cfqd = q->elevator->elevator_data; 394 struct cfq_data *cfqd = q->elevator->elevator_data;
395 395
396 return !cfqd->busy_queues; 396 return !cfqd->rq_queued;
397} 397}
398 398
399/* 399/*
@@ -842,7 +842,6 @@ static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
842static void cfq_del_rq_rb(struct request *rq) 842static void cfq_del_rq_rb(struct request *rq)
843{ 843{
844 struct cfq_queue *cfqq = RQ_CFQQ(rq); 844 struct cfq_queue *cfqq = RQ_CFQQ(rq);
845 struct cfq_data *cfqd = cfqq->cfqd;
846 const int sync = rq_is_sync(rq); 845 const int sync = rq_is_sync(rq);
847 846
848 BUG_ON(!cfqq->queued[sync]); 847 BUG_ON(!cfqq->queued[sync]);
@@ -850,8 +849,17 @@ static void cfq_del_rq_rb(struct request *rq)
850 849
851 elv_rb_del(&cfqq->sort_list, rq); 850 elv_rb_del(&cfqq->sort_list, rq);
852 851
853 if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list)) 852 if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list)) {
854 cfq_del_cfqq_rr(cfqd, cfqq); 853 /*
854 * Queue will be deleted from service tree when we actually
855 * expire it later. Right now just remove it from prio tree
856 * as it is empty.
857 */
858 if (cfqq->p_root) {
859 rb_erase(&cfqq->p_node, cfqq->p_root);
860 cfqq->p_root = NULL;
861 }
862 }
855} 863}
856 864
857static void cfq_add_rq_rb(struct request *rq) 865static void cfq_add_rq_rb(struct request *rq)
@@ -1065,6 +1073,9 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1065 cfq_log_cfqq(cfqd, cfqq, "resid=%ld", cfqq->slice_resid); 1073 cfq_log_cfqq(cfqd, cfqq, "resid=%ld", cfqq->slice_resid);
1066 } 1074 }
1067 1075
1076 if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list))
1077 cfq_del_cfqq_rr(cfqd, cfqq);
1078
1068 cfq_resort_rr_list(cfqd, cfqq); 1079 cfq_resort_rr_list(cfqd, cfqq);
1069 1080
1070 if (cfqq == cfqd->active_queue) 1081 if (cfqq == cfqd->active_queue)
@@ -1094,11 +1105,30 @@ static struct cfq_queue *cfq_get_next_queue(struct cfq_data *cfqd)
1094 service_tree_for(cfqd->serving_group, cfqd->serving_prio, 1105 service_tree_for(cfqd->serving_group, cfqd->serving_prio,
1095 cfqd->serving_type, cfqd); 1106 cfqd->serving_type, cfqd);
1096 1107
1108 if (!cfqd->rq_queued)
1109 return NULL;
1110
1097 if (RB_EMPTY_ROOT(&service_tree->rb)) 1111 if (RB_EMPTY_ROOT(&service_tree->rb))
1098 return NULL; 1112 return NULL;
1099 return cfq_rb_first(service_tree); 1113 return cfq_rb_first(service_tree);
1100} 1114}
1101 1115
1116static struct cfq_queue *cfq_get_next_queue_forced(struct cfq_data *cfqd)
1117{
1118 struct cfq_group *cfqg = &cfqd->root_group;
1119 struct cfq_queue *cfqq;
1120 int i, j;
1121 struct cfq_rb_root *st;
1122
1123 if (!cfqd->rq_queued)
1124 return NULL;
1125
1126 for_each_cfqg_st(cfqg, i, j, st)
1127 if ((cfqq = cfq_rb_first(st)) != NULL)
1128 return cfqq;
1129 return NULL;
1130}
1131
1102/* 1132/*
1103 * Get and set a new active queue for service. 1133 * Get and set a new active queue for service.
1104 */ 1134 */
@@ -1231,6 +1261,9 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1231 enum wl_prio_t prio = cfqq_prio(cfqq); 1261 enum wl_prio_t prio = cfqq_prio(cfqq);
1232 struct cfq_rb_root *service_tree = cfqq->service_tree; 1262 struct cfq_rb_root *service_tree = cfqq->service_tree;
1233 1263
1264 BUG_ON(!service_tree);
1265 BUG_ON(!service_tree->count);
1266
1234 /* We never do for idle class queues. */ 1267 /* We never do for idle class queues. */
1235 if (prio == IDLE_WORKLOAD) 1268 if (prio == IDLE_WORKLOAD)
1236 return false; 1269 return false;
@@ -1243,14 +1276,7 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1243 * Otherwise, we do only if they are the last ones 1276 * Otherwise, we do only if they are the last ones
1244 * in their service tree. 1277 * in their service tree.
1245 */ 1278 */
1246 if (!service_tree) 1279 return service_tree->count == 1;
1247 service_tree = service_tree_for(cfqq->cfqg, prio,
1248 cfqq_type(cfqq), cfqd);
1249
1250 if (service_tree->count == 0)
1251 return true;
1252
1253 return (service_tree->count == 1 && cfq_rb_first(service_tree) == cfqq);
1254} 1280}
1255 1281
1256static void cfq_arm_slice_timer(struct cfq_data *cfqd) 1282static void cfq_arm_slice_timer(struct cfq_data *cfqd)
@@ -1527,6 +1553,8 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
1527 if (!cfqq) 1553 if (!cfqq)
1528 goto new_queue; 1554 goto new_queue;
1529 1555
1556 if (!cfqd->rq_queued)
1557 return NULL;
1530 /* 1558 /*
1531 * The active queue has run out of time, expire it and select new. 1559 * The active queue has run out of time, expire it and select new.
1532 */ 1560 */
@@ -1589,6 +1617,9 @@ static int __cfq_forced_dispatch_cfqq(struct cfq_queue *cfqq)
1589 } 1617 }
1590 1618
1591 BUG_ON(!list_empty(&cfqq->fifo)); 1619 BUG_ON(!list_empty(&cfqq->fifo));
1620
1621 /* By default cfqq is not expired if it is empty. Do it explicitly */
1622 __cfq_slice_expired(cfqq->cfqd, cfqq, 0);
1592 return dispatched; 1623 return dispatched;
1593} 1624}
1594 1625
@@ -1600,14 +1631,9 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd)
1600{ 1631{
1601 struct cfq_queue *cfqq; 1632 struct cfq_queue *cfqq;
1602 int dispatched = 0; 1633 int dispatched = 0;
1603 int i, j;
1604 struct cfq_group *cfqg = &cfqd->root_group;
1605 struct cfq_rb_root *st;
1606 1634
1607 for_each_cfqg_st(cfqg, i, j, st) { 1635 while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL)
1608 while ((cfqq = cfq_rb_first(st)) != NULL) 1636 dispatched += __cfq_forced_dispatch_cfqq(cfqq);
1609 dispatched += __cfq_forced_dispatch_cfqq(cfqq);
1610 }
1611 1637
1612 cfq_slice_expired(cfqd, 0); 1638 cfq_slice_expired(cfqd, 0);
1613 BUG_ON(cfqd->busy_queues); 1639 BUG_ON(cfqd->busy_queues);
@@ -1776,13 +1802,13 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
1776 cfq_log_cfqq(cfqd, cfqq, "put_queue"); 1802 cfq_log_cfqq(cfqd, cfqq, "put_queue");
1777 BUG_ON(rb_first(&cfqq->sort_list)); 1803 BUG_ON(rb_first(&cfqq->sort_list));
1778 BUG_ON(cfqq->allocated[READ] + cfqq->allocated[WRITE]); 1804 BUG_ON(cfqq->allocated[READ] + cfqq->allocated[WRITE]);
1779 BUG_ON(cfq_cfqq_on_rr(cfqq));
1780 1805
1781 if (unlikely(cfqd->active_queue == cfqq)) { 1806 if (unlikely(cfqd->active_queue == cfqq)) {
1782 __cfq_slice_expired(cfqd, cfqq, 0); 1807 __cfq_slice_expired(cfqd, cfqq, 0);
1783 cfq_schedule_dispatch(cfqd); 1808 cfq_schedule_dispatch(cfqd);
1784 } 1809 }
1785 1810
1811 BUG_ON(cfq_cfqq_on_rr(cfqq));
1786 kmem_cache_free(cfq_pool, cfqq); 1812 kmem_cache_free(cfq_pool, cfqq);
1787} 1813}
1788 1814
@@ -2444,9 +2470,11 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
2444 if (cfq_class_idle(cfqq)) 2470 if (cfq_class_idle(cfqq))
2445 return true; 2471 return true;
2446 2472
2473 /* Allow preemption only if we are idling on sync-noidle tree */
2447 if (cfqd->serving_type == SYNC_NOIDLE_WORKLOAD && 2474 if (cfqd->serving_type == SYNC_NOIDLE_WORKLOAD &&
2448 cfqq_type(new_cfqq) == SYNC_NOIDLE_WORKLOAD && 2475 cfqq_type(new_cfqq) == SYNC_NOIDLE_WORKLOAD &&
2449 new_cfqq->service_tree->count == 1) 2476 new_cfqq->service_tree->count == 2 &&
2477 RB_EMPTY_ROOT(&cfqq->sort_list))
2450 return true; 2478 return true;
2451 2479
2452 /* 2480 /*