Commit f427d909648aa592c9588d0f66b5b457752a0cd1

Authored by Tejun Heo
1 parent b276a876a0

blkcg: implement blkcg_policy->on/offline_pd_fn() and blkcg_gq->online

Add two blkcg_policy methods, ->online_pd_fn() and ->offline_pd_fn(),
which are invoked as the policy_data gets activated and deactivated
while holding both blkcg and q locks.

Also, add blkcg_gq->online bool, which is set and cleared as the
blkcg_gq gets activated and deactivated.  This flag also is toggled
while holding both blkcg and q locks.

These will be used to implement hierarchical stats.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Vivek Goyal <vgoyal@redhat.com>

Showing 2 changed files with 27 additions and 1 deletions Side-by-side Diff

... ... @@ -182,7 +182,7 @@
182 182 struct blkcg_gq *new_blkg)
183 183 {
184 184 struct blkcg_gq *blkg;
185   - int ret;
  185 + int i, ret;
186 186  
187 187 WARN_ON_ONCE(!rcu_read_lock_held());
188 188 lockdep_assert_held(q->queue_lock);
189 189  
... ... @@ -218,7 +218,15 @@
218 218 if (likely(!ret)) {
219 219 hlist_add_head_rcu(&blkg->blkcg_node, &blkcg->blkg_list);
220 220 list_add(&blkg->q_node, &q->blkg_list);
  221 +
  222 + for (i = 0; i < BLKCG_MAX_POLS; i++) {
  223 + struct blkcg_policy *pol = blkcg_policy[i];
  224 +
  225 + if (blkg->pd[i] && pol->pd_online_fn)
  226 + pol->pd_online_fn(blkg);
  227 + }
221 228 }
  229 + blkg->online = true;
222 230 spin_unlock(&blkcg->lock);
223 231  
224 232 if (!ret)
... ... @@ -291,6 +299,7 @@
291 299 static void blkg_destroy(struct blkcg_gq *blkg)
292 300 {
293 301 struct blkcg *blkcg = blkg->blkcg;
  302 + int i;
294 303  
295 304 lockdep_assert_held(blkg->q->queue_lock);
296 305 lockdep_assert_held(&blkcg->lock);
... ... @@ -299,6 +308,14 @@
299 308 WARN_ON_ONCE(list_empty(&blkg->q_node));
300 309 WARN_ON_ONCE(hlist_unhashed(&blkg->blkcg_node));
301 310  
  311 + for (i = 0; i < BLKCG_MAX_POLS; i++) {
  312 + struct blkcg_policy *pol = blkcg_policy[i];
  313 +
  314 + if (blkg->pd[i] && pol->pd_offline_fn)
  315 + pol->pd_offline_fn(blkg);
  316 + }
  317 + blkg->online = false;
  318 +
302 319 radix_tree_delete(&blkcg->blkg_tree, blkg->q->id);
303 320 list_del_init(&blkg->q_node);
304 321 hlist_del_init_rcu(&blkg->blkcg_node);
... ... @@ -956,6 +973,8 @@
956 973 /* grab blkcg lock too while removing @pd from @blkg */
957 974 spin_lock(&blkg->blkcg->lock);
958 975  
  976 + if (pol->pd_offline_fn)
  977 + pol->pd_offline_fn(blkg);
959 978 if (pol->pd_exit_fn)
960 979 pol->pd_exit_fn(blkg);
961 980  
... ... @@ -106,12 +106,17 @@
106 106 /* reference count */
107 107 int refcnt;
108 108  
  109 + /* is this blkg online? protected by both blkcg and q locks */
  110 + bool online;
  111 +
109 112 struct blkg_policy_data *pd[BLKCG_MAX_POLS];
110 113  
111 114 struct rcu_head rcu_head;
112 115 };
113 116  
114 117 typedef void (blkcg_pol_init_pd_fn)(struct blkcg_gq *blkg);
  118 +typedef void (blkcg_pol_online_pd_fn)(struct blkcg_gq *blkg);
  119 +typedef void (blkcg_pol_offline_pd_fn)(struct blkcg_gq *blkg);
115 120 typedef void (blkcg_pol_exit_pd_fn)(struct blkcg_gq *blkg);
116 121 typedef void (blkcg_pol_reset_pd_stats_fn)(struct blkcg_gq *blkg);
117 122  
... ... @@ -124,6 +129,8 @@
124 129  
125 130 /* operations */
126 131 blkcg_pol_init_pd_fn *pd_init_fn;
  132 + blkcg_pol_online_pd_fn *pd_online_fn;
  133 + blkcg_pol_offline_pd_fn *pd_offline_fn;
127 134 blkcg_pol_exit_pd_fn *pd_exit_fn;
128 135 blkcg_pol_reset_pd_stats_fn *pd_reset_stats_fn;
129 136 };