aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-03-05 16:15:00 -0500
committerJens Axboe <axboe@kernel.dk>2012-03-06 15:27:22 -0500
commit72e06c255181537d0b3e1f657a9ed81655d745b1 (patch)
treeeb656df2ad23a7709b4e9fe58f1dabdc32be9ae9 /block/cfq-iosched.c
parent6ecf23afab13c39d3bb0e2d826d0984b0dd53733 (diff)
blkcg: shoot down blkio_groups on elevator switch
Elevator switch may involve changes to blkcg policies. Implement shoot down of blkio_groups. Combined with the previous bypass updates, the end goal is updating blkcg core such that it can ensure that blkcg's being affected become quiescent and don't have any per-blkg data hanging around before commencing any policy updates. Until queues are made aware of the policies that applies to them, as an interim step, all per-policy blkg data will be shot down. * blk-throtl doesn't need this change as it can't be disabled for a live queue; however, update it anyway as the scheduled blkg unification requires this behavior change. This means that blk-throtl configuration will be unnecessarily lost over elevator switch. This oddity will be removed after blkcg learns to associate individual policies with request_queues. * blk-throtl dosen't shoot down root_tg. This is to ease transition. Unified blkg will always have persistent root group and not shooting down root_tg for now eases transition to that point by avoiding having to update td->root_tg and is safe as blk-throtl can never be disabled -v2: Vivek pointed out that group list is not guaranteed to be empty on return from clear function if it raced cgroup removal and lost. Fix it by waiting a bit and retrying. This kludge will soon be removed once locking is updated such that blkg is never in limbo state between blkcg and request_queue locks. blk-throtl no longer shoots down root_tg to avoid breaking td->root_tg. Also, Nest queue_lock inside blkio_list_lock not the other way around to avoid introduce possible deadlock via blkcg lock. -v3: blkcg_clear_queue() repositioned and renamed to blkg_destroy_all() to increase consistency with later changes. cfq_clear_queue() updated to check q->elevator before dereferencing it to avoid NULL dereference on not fully initialized queues (used by later change). Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r--block/cfq-iosched.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 72680a6715f..61693d3404d 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1225,10 +1225,11 @@ static void cfq_destroy_cfqg(struct cfq_data *cfqd, struct cfq_group *cfqg)
1225 cfq_put_cfqg(cfqg); 1225 cfq_put_cfqg(cfqg);
1226} 1226}
1227 1227
1228static void cfq_release_cfq_groups(struct cfq_data *cfqd) 1228static bool cfq_release_cfq_groups(struct cfq_data *cfqd)
1229{ 1229{
1230 struct hlist_node *pos, *n; 1230 struct hlist_node *pos, *n;
1231 struct cfq_group *cfqg; 1231 struct cfq_group *cfqg;
1232 bool empty = true;
1232 1233
1233 hlist_for_each_entry_safe(cfqg, pos, n, &cfqd->cfqg_list, cfqd_node) { 1234 hlist_for_each_entry_safe(cfqg, pos, n, &cfqd->cfqg_list, cfqd_node) {
1234 /* 1235 /*
@@ -1238,7 +1239,10 @@ static void cfq_release_cfq_groups(struct cfq_data *cfqd)
1238 */ 1239 */
1239 if (!cfq_blkiocg_del_blkio_group(&cfqg->blkg)) 1240 if (!cfq_blkiocg_del_blkio_group(&cfqg->blkg))
1240 cfq_destroy_cfqg(cfqd, cfqg); 1241 cfq_destroy_cfqg(cfqd, cfqg);
1242 else
1243 empty = false;
1241 } 1244 }
1245 return empty;
1242} 1246}
1243 1247
1244/* 1248/*
@@ -1265,6 +1269,19 @@ static void cfq_unlink_blkio_group(void *key, struct blkio_group *blkg)
1265 spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); 1269 spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
1266} 1270}
1267 1271
1272static struct elevator_type iosched_cfq;
1273
1274static bool cfq_clear_queue(struct request_queue *q)
1275{
1276 lockdep_assert_held(q->queue_lock);
1277
1278 /* shoot down blkgs iff the current elevator is cfq */
1279 if (!q->elevator || q->elevator->type != &iosched_cfq)
1280 return true;
1281
1282 return cfq_release_cfq_groups(q->elevator->elevator_data);
1283}
1284
1268#else /* GROUP_IOSCHED */ 1285#else /* GROUP_IOSCHED */
1269static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd) 1286static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd)
1270{ 1287{
@@ -3875,6 +3892,7 @@ static struct elevator_type iosched_cfq = {
3875static struct blkio_policy_type blkio_policy_cfq = { 3892static struct blkio_policy_type blkio_policy_cfq = {
3876 .ops = { 3893 .ops = {
3877 .blkio_unlink_group_fn = cfq_unlink_blkio_group, 3894 .blkio_unlink_group_fn = cfq_unlink_blkio_group,
3895 .blkio_clear_queue_fn = cfq_clear_queue,
3878 .blkio_update_group_weight_fn = cfq_update_blkio_group_weight, 3896 .blkio_update_group_weight_fn = cfq_update_blkio_group_weight,
3879 }, 3897 },
3880 .plid = BLKIO_POLICY_PROP, 3898 .plid = BLKIO_POLICY_PROP,