[Devel] [PATCH RHEL7 v17 07/13] ve/cgroup: Added ve_owner field to cgroup

Kirill Tkhai ktkhai at virtuozzo.com
Thu Apr 23 11:39:57 MSK 2020


On 23.04.2020 11:17, Kirill Tkhai wrote:
> On 22.04.2020 20:00, 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.
>>
>> Signed-off-by: Valeriy Vdovin <valeriy.vdovin at virtuozzo.com>
>> ---
>>  include/linux/cgroup.h |  4 ++++
>>  kernel/cgroup.c        | 44 ++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 48 insertions(+)
>>
>> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
>> index 1bd0fe7..7ed718d 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 *ve_owner;
> 
> In case of you decided to use rcu in below, __rcu prefix is required here.

I say this, because you have rcu_dereference() in cgroup_get_ve_owner().
I do not know you really need RCU. If you don't need, remove rcu_dereference()
from cgroup_get_ve_owner. If you need RCU, add a description in patch comment,
why so.

> 
>>  };
>>  
>>  #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..42f77c6 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);
>> @@ -1647,6 +1683,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
>>  		const struct cred *cred;
>>  		int i;
>>  		struct css_set *cg;
>> +		root_cgrp->ve_owner = &ve0;
> 
> rcu_assign_pointer?
> 
>>  
>>  		BUG_ON(sb->s_root != NULL);
>>  
>> @@ -4254,12 +4291,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 +4309,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