aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-cgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/blk-cgroup.c')
-rw-r--r--block/blk-cgroup.c24
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
637static void blkg_rcu_free(struct rcu_head *rcu_head)
638{
639 blkg_free(container_of(rcu_head, struct blkio_group, rcu_head));
640}
641
642void __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}
658EXPORT_SYMBOL_GPL(__blkg_release);
659
636static void blkio_reset_stats_cpu(struct blkio_group *blkg) 660static 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;