blkcg: shoot down blkgs if all policies are deactivated
authorTejun Heo <tj@kernel.org>
Fri, 13 Apr 2012 20:11:35 +0000 (13:11 -0700)
committerJens Axboe <axboe@kernel.dk>
Fri, 20 Apr 2012 08:06:06 +0000 (10:06 +0200)
There's no reason to keep blkgs around if no policy is activated for
the queue.  This patch moves queue locking out of blkg_destroy_all()
and call it from blkg_deactivate_policy() on deactivation of the last
policy on the queue.

This change was suggested by Vivek.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-cgroup.c

index 10f0d2fc0b23596b0783f0142c74302fc5d89306..b1807d4ecedbcd44127d3ae03fc43d34b9b405f5 100644 (file)
@@ -258,7 +258,7 @@ static void blkg_destroy_all(struct request_queue *q)
 {
        struct blkio_group *blkg, *n;
 
-       spin_lock_irq(q->queue_lock);
+       lockdep_assert_held(q->queue_lock);
 
        list_for_each_entry_safe(blkg, n, &q->blkg_list, q_node) {
                struct blkio_cgroup *blkcg = blkg->blkcg;
@@ -267,8 +267,6 @@ static void blkg_destroy_all(struct request_queue *q)
                blkg_destroy(blkg);
                spin_unlock(&blkcg->lock);
        }
-
-       spin_unlock_irq(q->queue_lock);
 }
 
 static void blkg_rcu_free(struct rcu_head *rcu_head)
@@ -646,7 +644,10 @@ void blkcg_drain_queue(struct request_queue *q)
  */
 void blkcg_exit_queue(struct request_queue *q)
 {
+       spin_lock_irq(q->queue_lock);
        blkg_destroy_all(q);
+       spin_unlock_irq(q->queue_lock);
+
        blk_throtl_exit(q);
 }
 
@@ -802,6 +803,10 @@ void blkcg_deactivate_policy(struct request_queue *q,
 
        __clear_bit(pol->plid, q->blkcg_pols);
 
+       /* if no policy is left, no need for blkgs - shoot them down */
+       if (bitmap_empty(q->blkcg_pols, BLKCG_MAX_POLS))
+               blkg_destroy_all(q);
+
        list_for_each_entry(blkg, &q->blkg_list, q_node) {
                /* grab blkcg lock too while removing @pd from @blkg */
                spin_lock(&blkg->blkcg->lock);