diff options
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r-- | block/cfq-iosched.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index b9e483d9031e..063dcbb714e7 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -144,6 +144,7 @@ struct cfq_queue { | |||
144 | struct cfq_rb_root *service_tree; | 144 | struct cfq_rb_root *service_tree; |
145 | struct cfq_queue *new_cfqq; | 145 | struct cfq_queue *new_cfqq; |
146 | struct cfq_group *cfqg; | 146 | struct cfq_group *cfqg; |
147 | struct cfq_group *orig_cfqg; | ||
147 | /* Sectors dispatched in current dispatch round */ | 148 | /* Sectors dispatched in current dispatch round */ |
148 | unsigned long nr_sectors; | 149 | unsigned long nr_sectors; |
149 | }; | 150 | }; |
@@ -273,6 +274,7 @@ struct cfq_data { | |||
273 | unsigned int cfq_slice_async_rq; | 274 | unsigned int cfq_slice_async_rq; |
274 | unsigned int cfq_slice_idle; | 275 | unsigned int cfq_slice_idle; |
275 | unsigned int cfq_latency; | 276 | unsigned int cfq_latency; |
277 | unsigned int cfq_group_isolation; | ||
276 | 278 | ||
277 | struct list_head cic_list; | 279 | struct list_head cic_list; |
278 | 280 | ||
@@ -1120,6 +1122,33 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
1120 | struct cfq_rb_root *service_tree; | 1122 | struct cfq_rb_root *service_tree; |
1121 | int left; | 1123 | int left; |
1122 | int new_cfqq = 1; | 1124 | int new_cfqq = 1; |
1125 | int group_changed = 0; | ||
1126 | |||
1127 | #ifdef CONFIG_CFQ_GROUP_IOSCHED | ||
1128 | if (!cfqd->cfq_group_isolation | ||
1129 | && cfqq_type(cfqq) == SYNC_NOIDLE_WORKLOAD | ||
1130 | && cfqq->cfqg && cfqq->cfqg != &cfqd->root_group) { | ||
1131 | /* Move this cfq to root group */ | ||
1132 | cfq_log_cfqq(cfqd, cfqq, "moving to root group"); | ||
1133 | if (!RB_EMPTY_NODE(&cfqq->rb_node)) | ||
1134 | cfq_group_service_tree_del(cfqd, cfqq->cfqg); | ||
1135 | cfqq->orig_cfqg = cfqq->cfqg; | ||
1136 | cfqq->cfqg = &cfqd->root_group; | ||
1137 | atomic_inc(&cfqd->root_group.ref); | ||
1138 | group_changed = 1; | ||
1139 | } else if (!cfqd->cfq_group_isolation | ||
1140 | && cfqq_type(cfqq) == SYNC_WORKLOAD && cfqq->orig_cfqg) { | ||
1141 | /* cfqq is sequential now needs to go to its original group */ | ||
1142 | BUG_ON(cfqq->cfqg != &cfqd->root_group); | ||
1143 | if (!RB_EMPTY_NODE(&cfqq->rb_node)) | ||
1144 | cfq_group_service_tree_del(cfqd, cfqq->cfqg); | ||
1145 | cfq_put_cfqg(cfqq->cfqg); | ||
1146 | cfqq->cfqg = cfqq->orig_cfqg; | ||
1147 | cfqq->orig_cfqg = NULL; | ||
1148 | group_changed = 1; | ||
1149 | cfq_log_cfqq(cfqd, cfqq, "moved to origin group"); | ||
1150 | } | ||
1151 | #endif | ||
1123 | 1152 | ||
1124 | service_tree = service_tree_for(cfqq->cfqg, cfqq_prio(cfqq), | 1153 | service_tree = service_tree_for(cfqq->cfqg, cfqq_prio(cfqq), |
1125 | cfqq_type(cfqq), cfqd); | 1154 | cfqq_type(cfqq), cfqd); |
@@ -1190,7 +1219,7 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
1190 | rb_link_node(&cfqq->rb_node, parent, p); | 1219 | rb_link_node(&cfqq->rb_node, parent, p); |
1191 | rb_insert_color(&cfqq->rb_node, &service_tree->rb); | 1220 | rb_insert_color(&cfqq->rb_node, &service_tree->rb); |
1192 | service_tree->count++; | 1221 | service_tree->count++; |
1193 | if (add_front || !new_cfqq) | 1222 | if ((add_front || !new_cfqq) && !group_changed) |
1194 | return; | 1223 | return; |
1195 | cfq_group_service_tree_add(cfqd, cfqq->cfqg); | 1224 | cfq_group_service_tree_add(cfqd, cfqq->cfqg); |
1196 | } | 1225 | } |
@@ -2357,6 +2386,8 @@ static void cfq_put_queue(struct cfq_queue *cfqq) | |||
2357 | BUG_ON(cfq_cfqq_on_rr(cfqq)); | 2386 | BUG_ON(cfq_cfqq_on_rr(cfqq)); |
2358 | kmem_cache_free(cfq_pool, cfqq); | 2387 | kmem_cache_free(cfq_pool, cfqq); |
2359 | cfq_put_cfqg(cfqg); | 2388 | cfq_put_cfqg(cfqg); |
2389 | if (cfqq->orig_cfqg) | ||
2390 | cfq_put_cfqg(cfqq->orig_cfqg); | ||
2360 | } | 2391 | } |
2361 | 2392 | ||
2362 | /* | 2393 | /* |
@@ -3670,6 +3701,7 @@ static void *cfq_init_queue(struct request_queue *q) | |||
3670 | cfqd->cfq_slice_async_rq = cfq_slice_async_rq; | 3701 | cfqd->cfq_slice_async_rq = cfq_slice_async_rq; |
3671 | cfqd->cfq_slice_idle = cfq_slice_idle; | 3702 | cfqd->cfq_slice_idle = cfq_slice_idle; |
3672 | cfqd->cfq_latency = 1; | 3703 | cfqd->cfq_latency = 1; |
3704 | cfqd->cfq_group_isolation = 0; | ||
3673 | cfqd->hw_tag = -1; | 3705 | cfqd->hw_tag = -1; |
3674 | cfqd->last_end_sync_rq = jiffies; | 3706 | cfqd->last_end_sync_rq = jiffies; |
3675 | return cfqd; | 3707 | return cfqd; |
@@ -3740,6 +3772,7 @@ SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1); | |||
3740 | SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); | 3772 | SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); |
3741 | SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); | 3773 | SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); |
3742 | SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0); | 3774 | SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0); |
3775 | SHOW_FUNCTION(cfq_group_isolation_show, cfqd->cfq_group_isolation, 0); | ||
3743 | #undef SHOW_FUNCTION | 3776 | #undef SHOW_FUNCTION |
3744 | 3777 | ||
3745 | #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ | 3778 | #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ |
@@ -3772,6 +3805,7 @@ STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1); | |||
3772 | STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, | 3805 | STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, |
3773 | UINT_MAX, 0); | 3806 | UINT_MAX, 0); |
3774 | STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0); | 3807 | STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0); |
3808 | STORE_FUNCTION(cfq_group_isolation_store, &cfqd->cfq_group_isolation, 0, 1, 0); | ||
3775 | #undef STORE_FUNCTION | 3809 | #undef STORE_FUNCTION |
3776 | 3810 | ||
3777 | #define CFQ_ATTR(name) \ | 3811 | #define CFQ_ATTR(name) \ |
@@ -3788,6 +3822,7 @@ static struct elv_fs_entry cfq_attrs[] = { | |||
3788 | CFQ_ATTR(slice_async_rq), | 3822 | CFQ_ATTR(slice_async_rq), |
3789 | CFQ_ATTR(slice_idle), | 3823 | CFQ_ATTR(slice_idle), |
3790 | CFQ_ATTR(low_latency), | 3824 | CFQ_ATTR(low_latency), |
3825 | CFQ_ATTR(group_isolation), | ||
3791 | __ATTR_NULL | 3826 | __ATTR_NULL |
3792 | }; | 3827 | }; |
3793 | 3828 | ||