devcg: use css_online and css_offline
Allocate resources and change behavior only when online. This is needed in order to determine if a node is suitable for hierarchy propagation or if it's being removed. Locking: Both functions take devcgroup_mutex to make changes to device_cgroup structure. Hierarchy propagation will also take devcgroup_mutex before walking the tree while walking the tree itself is protected by rcu lock. Acked-by: Tejun Heo <tj@kernel.org> Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Cc: Tejun Heo <tj@kernel.org> Cc: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Aristeu Rozanski <aris@redhat.com> Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
c39a2a3018
commit
1909554c97
1 changed files with 42 additions and 17 deletions
|
@ -185,36 +185,59 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup)
|
|||
__dev_exception_clean(dev_cgroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* devcgroup_online - initializes devcgroup's behavior and exceptions based on
|
||||
* parent's
|
||||
* @cgroup: cgroup getting online
|
||||
* returns 0 in case of success, error code otherwise
|
||||
*/
|
||||
static int devcgroup_online(struct cgroup *cgroup)
|
||||
{
|
||||
struct dev_cgroup *dev_cgroup, *parent_dev_cgroup = NULL;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&devcgroup_mutex);
|
||||
dev_cgroup = cgroup_to_devcgroup(cgroup);
|
||||
if (cgroup->parent)
|
||||
parent_dev_cgroup = cgroup_to_devcgroup(cgroup->parent);
|
||||
|
||||
if (parent_dev_cgroup == NULL)
|
||||
dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW;
|
||||
else {
|
||||
ret = dev_exceptions_copy(&dev_cgroup->exceptions,
|
||||
&parent_dev_cgroup->exceptions);
|
||||
if (!ret)
|
||||
dev_cgroup->behavior = parent_dev_cgroup->behavior;
|
||||
}
|
||||
mutex_unlock(&devcgroup_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void devcgroup_offline(struct cgroup *cgroup)
|
||||
{
|
||||
struct dev_cgroup *dev_cgroup = cgroup_to_devcgroup(cgroup);
|
||||
|
||||
mutex_lock(&devcgroup_mutex);
|
||||
dev_cgroup->behavior = DEVCG_DEFAULT_NONE;
|
||||
mutex_unlock(&devcgroup_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* called from kernel/cgroup.c with cgroup_lock() held.
|
||||
*/
|
||||
static struct cgroup_subsys_state *devcgroup_css_alloc(struct cgroup *cgroup)
|
||||
{
|
||||
struct dev_cgroup *dev_cgroup, *parent_dev_cgroup;
|
||||
struct dev_cgroup *dev_cgroup;
|
||||
struct cgroup *parent_cgroup;
|
||||
int ret;
|
||||
|
||||
dev_cgroup = kzalloc(sizeof(*dev_cgroup), GFP_KERNEL);
|
||||
if (!dev_cgroup)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
INIT_LIST_HEAD(&dev_cgroup->exceptions);
|
||||
dev_cgroup->behavior = DEVCG_DEFAULT_NONE;
|
||||
parent_cgroup = cgroup->parent;
|
||||
|
||||
if (parent_cgroup == NULL)
|
||||
dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW;
|
||||
else {
|
||||
parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup);
|
||||
mutex_lock(&devcgroup_mutex);
|
||||
ret = dev_exceptions_copy(&dev_cgroup->exceptions,
|
||||
&parent_dev_cgroup->exceptions);
|
||||
dev_cgroup->behavior = parent_dev_cgroup->behavior;
|
||||
mutex_unlock(&devcgroup_mutex);
|
||||
if (ret) {
|
||||
kfree(dev_cgroup);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
}
|
||||
|
||||
return &dev_cgroup->css;
|
||||
}
|
||||
|
||||
|
@ -587,6 +610,8 @@ struct cgroup_subsys devices_subsys = {
|
|||
.can_attach = devcgroup_can_attach,
|
||||
.css_alloc = devcgroup_css_alloc,
|
||||
.css_free = devcgroup_css_free,
|
||||
.css_online = devcgroup_online,
|
||||
.css_offline = devcgroup_offline,
|
||||
.subsys_id = devices_subsys_id,
|
||||
.base_cftypes = dev_cgroup_files,
|
||||
|
||||
|
|
Loading…
Reference in a new issue