[Devel] [PATCH RHEL7 v19 07/13] ve/cgroup: Added ve_owner field to cgroup
Kirill Tkhai
ktkhai at virtuozzo.com
Fri Apr 24 11:35:18 MSK 2020
On 23.04.2020 18:44, Valeriy Vdovin wrote:
> Each cgroup representing a host or a container root of
> cgroup subsystem hierarhy will have this field set to
> a valid ve_struct, that owns this root. This way each
> cgroup in a system will be able to know it's owning VE.
> Non root cgroups will have this field set to NULL, this
> is an optimization for cleanup code: at VE destruction
> we only need to iterate over all root cgroups to clean
> reference to former owning VE, rather than over all
> cgroup hierarchy.
> Still any cgroup that wants to know about it's owning
> VE can find it's virtual root cgroup and read it's
> ve_owner field.
>
> cgroup->ve_owner is declared as RCU pointer, because it fits
> RCU semantics - rare writes/often reads. ve_owner will be
> read from multiple locations in code in further patches and
> is only rarely set at cgroup_mark_ve_root/cgroup_mount.
> cgroup_get_ve_owner is a read wrapper for this purpose.
>
> Signed-off-by: Valeriy Vdovin <valeriy.vdovin at virtuozzo.com>
Reviewed-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> ---
> include/linux/cgroup.h | 4 ++++
> kernel/cgroup.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 49 insertions(+)
>
> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
> index 1bd0fe7..ad437a8 100644
> --- a/include/linux/cgroup.h
> +++ b/include/linux/cgroup.h
> @@ -292,6 +292,9 @@ struct cgroup {
> /* directory xattrs */
> struct simple_xattrs xattrs;
> u64 subgroups_limit;
> +
> + /* ve_owner, responsible for running release agent. */
> + struct ve_struct __rcu *ve_owner;
> };
>
> #define MAX_CGROUP_ROOT_NAMELEN 64
> @@ -637,6 +640,7 @@ int cgroup_task_count(const struct cgroup *cgrp);
> #ifdef CONFIG_VE
> void cgroup_mark_ve_roots(struct ve_struct *ve);
> void cgroup_unmark_ve_roots(struct ve_struct *ve);
> +struct ve_struct *cgroup_get_ve_owner(struct cgroup *cgrp);
> #endif
>
> /*
> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
> index 010a23e..c4e0126 100644
> --- a/kernel/cgroup.c
> +++ b/kernel/cgroup.c
> @@ -805,6 +805,42 @@ static struct cgroup_name *cgroup_alloc_name(struct dentry *dentry)
> return name;
> }
>
> +struct cgroup *cgroup_get_local_root(struct cgroup *cgrp)
> +{
> + /*
> + * Find nearest root cgroup, which might be host cgroup root
> + * or ve cgroup root.
> + *
> + * <host_root_cgroup> -> local_root
> + * \ ^
> + * <cgroup> |
> + * \ |
> + * <cgroup> ---> from here
> + * \
> + * <ve_root_cgroup> -> local_root
> + * \ ^
> + * <cgroup> |
> + * \ |
> + * <cgroup> ---> from here
> + */
> + while (cgrp->parent && !test_bit(CGRP_VE_ROOT, &cgrp->flags))
> + cgrp = cgrp->parent;
> +
> + return cgrp;
> +}
> +
> +struct ve_struct *cgroup_get_ve_owner(struct cgroup *cgrp)
> +{
> + struct ve_struct *ve;
> + /* Caller should hold RCU */
> +
> + cgrp = cgroup_get_local_root(cgrp);
> + ve = rcu_dereference(cgrp->ve_owner);
> + if (!ve)
> + ve = get_ve0();
> + return ve;
> +}
> +
> static void cgroup_free_fn(struct work_struct *work)
> {
> struct cgroup *cgrp = container_of(work, struct cgroup, destroy_work);
> @@ -1627,6 +1663,8 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
> ret = PTR_ERR(new_root);
> goto drop_modules;
> }
> +
> + RCU_INIT_POINTER(new_root->top_cgroup.ve_owner, &ve0);
> opts.new_root = new_root;
>
> /* Locate an existing or new sb for this hierarchy */
> @@ -4254,12 +4292,14 @@ void cgroup_mark_ve_roots(struct ve_struct *ve)
> mutex_lock(&cgroup_mutex);
> for_each_active_root(root) {
> cgrp = task_cgroup_from_root(ve->init_task, root);
> + rcu_assign_pointer(cgrp->ve_owner, ve);
> set_bit(CGRP_VE_ROOT, &cgrp->flags);
>
> if (test_bit(cpu_cgroup_subsys_id, &root->subsys_mask))
> link_ve_root_cpu_cgroup(cgrp);
> }
> mutex_unlock(&cgroup_mutex);
> + synchronize_rcu();
> }
>
> void cgroup_unmark_ve_roots(struct ve_struct *ve)
> @@ -4270,9 +4310,14 @@ void cgroup_unmark_ve_roots(struct ve_struct *ve)
> mutex_lock(&cgroup_mutex);
> for_each_active_root(root) {
> cgrp = css_cgroup_from_root(ve->root_css_set, root);
> + BUG_ON(!rcu_dereference_protected(cgrp->ve_owner,
> + lockdep_is_held(&cgroup_mutex)));
> + rcu_assign_pointer(cgrp->ve_owner, NULL);
> clear_bit(CGRP_VE_ROOT, &cgrp->flags);
> }
> mutex_unlock(&cgroup_mutex);
> + /* ve_owner == NULL will be visible */
> + synchronize_rcu();
> }
>
> struct cgroup *cgroup_get_ve_root(struct cgroup *cgrp)
>
More information about the Devel
mailing list