diff options
| -rw-r--r-- | block/blk-cgroup.c | 25 | 
1 files changed, 15 insertions, 10 deletions
| diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 290792a13e3c..db30b6beee72 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -235,8 +235,13 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,  	blkg->online = true;  	spin_unlock(&blkcg->lock); -	if (!ret) +	if (!ret) { +		if (blkcg == &blkcg_root) { +			q->root_blkg = blkg; +			q->root_rl.blkg = blkg; +		}  		return blkg; +	}  	/* @blkg failed fully initialized, use the usual release path */  	blkg_put(blkg); @@ -335,6 +340,15 @@ static void blkg_destroy(struct blkcg_gq *blkg)  		rcu_assign_pointer(blkcg->blkg_hint, NULL);  	/* +	 * If root blkg is destroyed.  Just clear the pointer since root_rl +	 * does not take reference on root blkg. +	 */ +	if (blkcg == &blkcg_root) { +		blkg->q->root_blkg = NULL; +		blkg->q->root_rl.blkg = NULL; +	} + +	/*  	 * Put the reference taken at the time of creation so that when all  	 * queues are gone, group can be destroyed.  	 */ @@ -360,13 +374,6 @@ static void blkg_destroy_all(struct request_queue *q)  		blkg_destroy(blkg);  		spin_unlock(&blkcg->lock);  	} - -	/* -	 * root blkg is destroyed.  Just clear the pointer since -	 * root_rl does not take reference on root blkg. -	 */ -	q->root_blkg = NULL; -	q->root_rl.blkg = NULL;  }  /* @@ -973,8 +980,6 @@ int blkcg_activate_policy(struct request_queue *q,  		ret = PTR_ERR(blkg);  		goto out_unlock;  	} -	q->root_blkg = blkg; -	q->root_rl.blkg = blkg;  	list_for_each_entry(blkg, &q->blkg_list, q_node)  		cnt++; | 
