aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-cgroup.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/blk-cgroup.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/blk-cgroup.c')
-rw-r--r--block/blk-cgroup.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 970a717a056f..159aef59589f 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -17,8 +17,9 @@
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/blkdev.h> 18#include <linux/blkdev.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include "blk-cgroup.h"
21#include <linux/genhd.h> 20#include <linux/genhd.h>
21#include <linux/delay.h>
22#include "blk-cgroup.h"
22 23
23#define MAX_KEY_LEN 100 24#define MAX_KEY_LEN 100
24 25
@@ -546,6 +547,37 @@ struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key)
546} 547}
547EXPORT_SYMBOL_GPL(blkiocg_lookup_group); 548EXPORT_SYMBOL_GPL(blkiocg_lookup_group);
548 549
550void blkg_destroy_all(struct request_queue *q)
551{
552 struct blkio_policy_type *pol;
553
554 while (true) {
555 bool done = true;
556
557 spin_lock(&blkio_list_lock);
558 spin_lock_irq(q->queue_lock);
559
560 /*
561 * clear_queue_fn() might return with non-empty group list
562 * if it raced cgroup removal and lost. cgroup removal is
563 * guaranteed to make forward progress and retrying after a
564 * while is enough. This ugliness is scheduled to be
565 * removed after locking update.
566 */
567 list_for_each_entry(pol, &blkio_list, list)
568 if (!pol->ops.blkio_clear_queue_fn(q))
569 done = false;
570
571 spin_unlock_irq(q->queue_lock);
572 spin_unlock(&blkio_list_lock);
573
574 if (done)
575 break;
576
577 msleep(10); /* just some random duration I like */
578 }
579}
580
549static void blkio_reset_stats_cpu(struct blkio_group *blkg) 581static void blkio_reset_stats_cpu(struct blkio_group *blkg)
550{ 582{
551 struct blkio_group_stats_cpu *stats_cpu; 583 struct blkio_group_stats_cpu *stats_cpu;