Skip to content

Commit

Permalink
blkcg: invoke blkcg_policy->pd_init() after parent is linked
Browse files Browse the repository at this point in the history
Currently, when creating a new blkcg_gq, each policy's pd_init_fn() is
invoked in blkg_alloc() before the parent is linked.  This makes it
difficult for policies to perform initializations which are dependent
on the parent.

This patch moves pd_init_fn() invocations to blkg_create() after the
parent blkg is linked where the new blkg is fully initialized.  As
this means that blkg_free() can't assume that pd's are initialized,
pd_exit_fn() invocations are moved to __blkg_release().  This
guarantees that pd_exit_fn() is also invoked with fully initialized
blkgs with valid parent pointers.

This will help implementing hierarchy support in blk-throttle.

Signed-off-by: Tejun Heo <[email protected]>
Acked-by: Vivek Goyal <[email protected]>
  • Loading branch information
htejun committed May 14, 2013
1 parent aa539cb commit db61367
Showing 1 changed file with 22 additions and 17 deletions.
39 changes: 22 additions & 17 deletions block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,8 @@ static void blkg_free(struct blkcg_gq *blkg)
if (!blkg)
return;

for (i = 0; i < BLKCG_MAX_POLS; i++) {
struct blkcg_policy *pol = blkcg_policy[i];
struct blkg_policy_data *pd = blkg->pd[i];

if (!pd)
continue;

if (pol && pol->pd_exit_fn)
pol->pd_exit_fn(blkg);

kfree(pd);
}
for (i = 0; i < BLKCG_MAX_POLS; i++)
kfree(blkg->pd[i]);

blk_exit_rl(&blkg->rl);
kfree(blkg);
Expand Down Expand Up @@ -114,10 +104,6 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q,
blkg->pd[i] = pd;
pd->blkg = blkg;
pd->plid = i;

/* invoke per-policy init */
if (pol->pd_init_fn)
pol->pd_init_fn(blkg);
}

return blkg;
Expand Down Expand Up @@ -214,7 +200,7 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
}
blkg = new_blkg;

/* link parent and insert */
/* link parent */
if (blkcg_parent(blkcg)) {
blkg->parent = __blkg_lookup(blkcg_parent(blkcg), q, false);
if (WARN_ON_ONCE(!blkg->parent)) {
Expand All @@ -224,6 +210,15 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
blkg_get(blkg->parent);
}

/* invoke per-policy init */
for (i = 0; i < BLKCG_MAX_POLS; i++) {
struct blkcg_policy *pol = blkcg_policy[i];

if (blkg->pd[i] && pol->pd_init_fn)
pol->pd_init_fn(blkg);
}

/* insert */
spin_lock(&blkcg->lock);
ret = radix_tree_insert(&blkcg->blkg_tree, q->id, blkg);
if (likely(!ret)) {
Expand Down Expand Up @@ -381,6 +376,16 @@ static void blkg_rcu_free(struct rcu_head *rcu_head)

void __blkg_release(struct blkcg_gq *blkg)
{
int i;

/* tell policies that this one is being freed */
for (i = 0; i < BLKCG_MAX_POLS; i++) {
struct blkcg_policy *pol = blkcg_policy[i];

if (blkg->pd[i] && pol->pd_exit_fn)
pol->pd_exit_fn(blkg);
}

/* release the blkcg and parent blkg refs this blkg has been holding */
css_put(&blkg->blkcg->css);
if (blkg->parent)
Expand Down

0 comments on commit db61367

Please sign in to comment.