From: Lu Jialin lujialin4@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8LY4S
-------------------------------
Add cgroup1_get_from_id() function to help cgroupv1 get cgroup through cgroup inode;
The patch also export cgroup_tryget_css(), which will be used later
Signed-off-by: Lu Jialin lujialin4@huawei.com Signed-off-by: chenridong chenridong@huawei.com --- include/linux/cgroup-defs.h | 2 ++ include/linux/cgroup.h | 1 + kernel/cgroup/cgroup.c | 59 +++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+)
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 265da00a1a8b..013ea018cbd4 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -778,6 +778,8 @@ static inline void cgroup_threadgroup_change_end(struct task_struct *tsk) percpu_up_read(&cgroup_threadgroup_rwsem); }
+struct cgroup_subsys_state *cgroup_tryget_css(struct cgroup *cgrp, + struct cgroup_subsys *ss); #else /* CONFIG_CGROUPS */
#define CGROUP_SUBSYS_COUNT 0 diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index b307013b9c6c..419eecb901e6 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -633,6 +633,7 @@ static inline void cgroup_kthread_ready(void) }
void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen); +struct cgroup *cgroup1_get_from_id(struct cgroup_root *root, u64 id); struct cgroup *cgroup_get_from_id(u64 id); #else /* !CONFIG_CGROUPS */
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 518725b57200..2d607a2f7028 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -492,6 +492,28 @@ static struct cgroup_subsys_state *cgroup_css(struct cgroup *cgrp, return &cgrp->self; }
+/** + * cgroup_tryget_css - try to get a cgroup's css for the specified subsystem + * @cgrp: the cgroup of interest + * @ss: the subsystem of interest + * + * Find and get @cgrp's css associated with @ss. If the css doesn't exist + * or is offline, %NULL is returned. + */ +struct cgroup_subsys_state *cgroup_tryget_css(struct cgroup *cgrp, + struct cgroup_subsys *ss) +{ + struct cgroup_subsys_state *css; + + rcu_read_lock(); + css = cgroup_css(cgrp, ss); + if (css && !css_tryget_online(css)) + css = NULL; + rcu_read_unlock(); + + return css; +} + /** * cgroup_e_css_by_mask - obtain a cgroup's effective css for the specified ss * @cgrp: the cgroup of interest @@ -6302,6 +6324,43 @@ int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns, return retval; }
+struct cgroup *cgroup1_get_from_id(struct cgroup_root *root, u64 id) +{ + struct kernfs_node *kn; + struct cgroup *cgrp, *root_cgrp; + + kn = kernfs_find_and_get_node_by_id(root->kf_root, id); + if (!kn) + return ERR_PTR(-ENOENT); + + if (kernfs_type(kn) != KERNFS_DIR) { + kernfs_put(kn); + return ERR_PTR(-ENOENT); + } + + rcu_read_lock(); + + cgrp = rcu_dereference(*(void __rcu __force **)&kn->priv); + if (cgrp && !cgroup_tryget(cgrp)) + cgrp = NULL; + + rcu_read_unlock(); + kernfs_put(kn); + + if (!cgrp) + return ERR_PTR(-ENOENT); + + spin_lock_irq(&css_set_lock); + root_cgrp = current_cgns_cgroup_from_root(root); + spin_unlock_irq(&css_set_lock); + if (!cgroup_is_descendant(cgrp, root_cgrp)) { + cgroup_put(cgrp); + return ERR_PTR(-ENOENT); + } + + return cgrp; +} + /** * cgroup_fork - initialize cgroup related fields during copy_process() * @child: pointer to task_struct of forking parent process.