diff options
author | Tejun Heo <tj@kernel.org> | 2012-03-05 16:15:15 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-03-06 15:27:23 -0500 |
commit | 1adaf3dde37a8b9b59ea59c5f58fed7761178383 (patch) | |
tree | e4a46485b1bf0370aa41a5b9a8f138fba34c9d23 /block/blk-cgroup.c | |
parent | 0381411e4b1a52cee134eb73750e5e3cc1155d09 (diff) |
blkcg: move refcnt to blkcg core
Currently, blkcg policy implementations manage blkg refcnt duplicating
mostly identical code in both policies. This patch moves refcnt to
blkg and let blkcg core handle refcnt and freeing of blkgs.
* cfq blkgs now also get freed via RCU.
* cfq blkgs lose RB_EMPTY_ROOT() sanity check on blkg free. If
necessary, we can add blkio_exit_group_fn() to resurrect this.
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.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 14367499cfed..3b6a0e1265aa 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -463,6 +463,7 @@ static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg, | |||
463 | rcu_assign_pointer(blkg->q, q); | 463 | rcu_assign_pointer(blkg->q, q); |
464 | blkg->blkcg = blkcg; | 464 | blkg->blkcg = blkcg; |
465 | blkg->plid = pol->plid; | 465 | blkg->plid = pol->plid; |
466 | blkg->refcnt = 1; | ||
466 | cgroup_path(blkcg->css.cgroup, blkg->path, sizeof(blkg->path)); | 467 | cgroup_path(blkcg->css.cgroup, blkg->path, sizeof(blkg->path)); |
467 | 468 | ||
468 | /* alloc per-policy data */ | 469 | /* alloc per-policy data */ |
@@ -633,6 +634,29 @@ void blkg_destroy_all(struct request_queue *q) | |||
633 | } | 634 | } |
634 | } | 635 | } |
635 | 636 | ||
637 | static void blkg_rcu_free(struct rcu_head *rcu_head) | ||
638 | { | ||
639 | blkg_free(container_of(rcu_head, struct blkio_group, rcu_head)); | ||
640 | } | ||
641 | |||
642 | void __blkg_release(struct blkio_group *blkg) | ||
643 | { | ||
644 | /* release the extra blkcg reference this blkg has been holding */ | ||
645 | css_put(&blkg->blkcg->css); | ||
646 | |||
647 | /* | ||
648 | * A group is freed in rcu manner. But having an rcu lock does not | ||
649 | * mean that one can access all the fields of blkg and assume these | ||
650 | * are valid. For example, don't try to follow throtl_data and | ||
651 | * request queue links. | ||
652 | * | ||
653 | * Having a reference to blkg under an rcu allows acess to only | ||
654 | * values local to groups like group stats and group rate limits | ||
655 | */ | ||
656 | call_rcu(&blkg->rcu_head, blkg_rcu_free); | ||
657 | } | ||
658 | EXPORT_SYMBOL_GPL(__blkg_release); | ||
659 | |||
636 | static void blkio_reset_stats_cpu(struct blkio_group *blkg) | 660 | static void blkio_reset_stats_cpu(struct blkio_group *blkg) |
637 | { | 661 | { |
638 | struct blkio_group_stats_cpu *stats_cpu; | 662 | struct blkio_group_stats_cpu *stats_cpu; |