cgroup: add cgroup_subsys->css_released()
Tejun Heo
maintainerPATCH 1/3 cgroup: add cgroup_subsys->css_released()
Add a new cgroup subsys callback css_released(). This is called when the reference count of the css (cgroup_subsys_state) reaches zero before RCU scheduling free.
--- include/linux/cgroup.h | 1 + kernel/cgroup.c | 2 ++ 2 files changed, 3 insertions(+)
include/linux/cgroup.h +1 -0
@@ -612,6 +612,7 @@ struct cgroup_subsys {struct cgroup_subsys_state *(*css_alloc)(struct cgroup_subsys_state *parent_css);int (*css_online)(struct cgroup_subsys_state *css);void (*css_offline)(struct cgroup_subsys_state *css); +void (*css_released)(struct cgroup_subsys_state *css);void (*css_free)(struct cgroup_subsys_state *css);void (*css_reset)(struct cgroup_subsys_state *css);
kernel/cgroup.c +2 -0
@@ -4380,6 +4380,8 @@ static void css_release_work_fn(struct wif (ss) {/* css release path */ cgroup_idr_remove (&ss->css_idr, css->id); +if (ss->css_released) + ss->css_released (css); }else {/* cgroup release path */ cgroup_idr_remove (&cgrp->root->cgroup_idr, cgrp->id);
Tejun Heo
maintainerPATCH 2/3 cgroup: add cgroup_subsys->css_e_css_changed()
Add a new cgroup_subsys operatoin ->css_e_css_changed(). This is invoked if any of the effective csses seen from the css's cgroup may have changed. This will be used to implement cgroup writeback support.
--- include/linux/cgroup.h | 1 + kernel/cgroup.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+)
include/linux/cgroup.h +1 -0
@@ -615,6 +615,7 @@ struct cgroup_subsys {void (*css_released)(struct cgroup_subsys_state *css);void (*css_free)(struct cgroup_subsys_state *css);void (*css_reset)(struct cgroup_subsys_state *css); +void (*css_e_css_changed)(struct cgroup_subsys_state *css);int (*can_attach)(struct cgroup_subsys_state *css,struct cgroup_taskset *tset);
kernel/cgroup.c +18 -0
@@ -2836,6 +2836,24 @@ static ssize_t cgroup_subtree_control_wr } } +/* +* The effective csses of all the descendants (excluding @cgrp) may +* have changed. Subsystems can optionally subscribe to this event +* by implementing ->css_e_css_changed() which is invoked if any of +* the effective csses seen from the css's cgroup may have changed. +*/ +for_each_subsys (ss, ssid) { +struct cgroup_subsys_state *this_css =cgroup_css (cgrp, ss); +struct cgroup_subsys_state *css; + +if (!ss->css_e_css_changed || !this_css) +continue ; + +css_for_each_descendant_pre (css, this_css) +if (css != this_css) + ss->css_e_css_changed (css); + } +kernfs_activate (cgrp->kn); ret =0 ; out_unlock:
Tejun Heo
maintainerPATCH 3/3 cgroup: implement cgroup_get_e_css()
Implement cgroup_get_e_css() which finds and gets the effective css for the specified cgroup and subsystem combination. This function always returns a valid pinned css. This will be used by cgroup writeback support.
While at it, add comment to cgroup_e_css() to explain why that function is different from cgroup_get_e_css() and has to test cgrp->child_subsys_mask instead of cgroup_css(cgrp, ss).
--- include/linux/cgroup.h | 2 ++ kernel/cgroup.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+)
include/linux/cgroup.h +2 -0
@@ -910,6 +910,8 @@ void css_task_iter_end(struct css_task_iint cgroup_attach_task_all (struct task_struct *from,struct task_struct *);int cgroup_transfer_tasks (struct cgroup *to,struct cgroup *from); +struct cgroup_subsys_state *cgroup_get_e_css (struct cgroup *cgroup, +struct cgroup_subsys *ss);struct cgroup_subsys_state *css_tryget_online_from_dir (struct dentry *dentry,struct cgroup_subsys *ss);
kernel/cgroup.c +37 -0
@@ -277,6 +277,10 @@ static struct cgroup_subsys_state *cgrouif (!(cgrp->root->subsys_mask & (1 << ss->id)))return NULL ; +/* +* This function is used while updating css associations and thus +* can't test the csses directly. Use ->child_subsys_mask. +*/ while (cgroup_parent (cgrp) && !(cgroup_parent (cgrp)->child_subsys_mask & (1 << ss->id))) cgrp =cgroup_parent (cgrp);
@@ -284,6 +288,39 @@ static struct cgroup_subsys_state *cgroureturn cgroup_css (cgrp, ss); } +/** +* cgroup_get_e_css - get a cgroup's effective css for the specified subsystem +* @cgrp: the cgroup of interest +* @ss: the subsystem of interest +* +* Find and get the effective css of @cgrp for @ss. The effective css is +* defined as the matching css of the nearest ancestor including self which +* has @ss enabled. If @ss is not mounted on the hierarchy @cgrp is on, +* the root css is returned, so this function always returns a valid css. +* The returned css must be put using css_put(). +*/ +struct cgroup_subsys_state *cgroup_get_e_css (struct cgroup *cgrp, +struct cgroup_subsys *ss) +{ +struct cgroup_subsys_state *css; + +rcu_read_lock (); + +do { + css =cgroup_css (cgrp, ss); + +if (css &&css_tryget_online (css)) + goto out_unlock; + cgrp =cgroup_parent (cgrp); + }while (cgrp); + + css = init_css_set.subsys[ss->id]; +css_get (css); +out_unlock: +rcu_read_unlock (); +return css; +} +/* convenient tests for these bits */ static inline bool cgroup_is_dead (const struct cgroup *cgrp) {
Re: [PATCH 3/3 cgroup/for-3.19] cgroup: implement cgroup_get_e_css()
Quoted 10 lines · Tejun Heo
Implement
cgroup_get_e_css()which finds and gets the effective css for the specified cgroup and subsystem combination. This function always returns a valid pinned css. This will be used by cgroup writeback support.While at it, add comment to
cgroup_e_css()to explain why that function is different fromcgroup_get_e_css()and has to testcgrp->child_subsys_maskinstead ofcgroup_css(cgrp, ss).Signed-off-by Tejun Heo <[email protected]>
For all 3 patches:
Tejun Heo
maintainerRe: [PATCH 3/3 cgroup/for-3.19] cgroup: implement cgroup_get_e_css()
Quoted 3 lines · Zefan Li
For all 3 patches:
Acked-by Zefan Li <[email protected]>
Applied 1-3 to cgroup/for-3.19.
Thanks.
Signature · 1 line
tejun