Commit f427d909648aa592c9588d0f66b5b457752a0cd1
1 parent
b276a876a0
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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
block/blk-cgroup.c
... | ... | @@ -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 |
block/blk-cgroup.h
... | ... | @@ -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 | }; |