Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Aristeu Rozanski and committed by
Tejun Heo
1909554c c39a2a30

+42 -17
+42 -17
security/device_cgroup.c
··· 185 185 __dev_exception_clean(dev_cgroup); 186 186 } 187 187 188 + /** 189 + * devcgroup_online - initializes devcgroup's behavior and exceptions based on 190 + * parent's 191 + * @cgroup: cgroup getting online 192 + * returns 0 in case of success, error code otherwise 193 + */ 194 + static int devcgroup_online(struct cgroup *cgroup) 195 + { 196 + struct dev_cgroup *dev_cgroup, *parent_dev_cgroup = NULL; 197 + int ret = 0; 198 + 199 + mutex_lock(&devcgroup_mutex); 200 + dev_cgroup = cgroup_to_devcgroup(cgroup); 201 + if (cgroup->parent) 202 + parent_dev_cgroup = cgroup_to_devcgroup(cgroup->parent); 203 + 204 + if (parent_dev_cgroup == NULL) 205 + dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW; 206 + else { 207 + ret = dev_exceptions_copy(&dev_cgroup->exceptions, 208 + &parent_dev_cgroup->exceptions); 209 + if (!ret) 210 + dev_cgroup->behavior = parent_dev_cgroup->behavior; 211 + } 212 + mutex_unlock(&devcgroup_mutex); 213 + 214 + return ret; 215 + } 216 + 217 + static void devcgroup_offline(struct cgroup *cgroup) 218 + { 219 + struct dev_cgroup *dev_cgroup = cgroup_to_devcgroup(cgroup); 220 + 221 + mutex_lock(&devcgroup_mutex); 222 + dev_cgroup->behavior = DEVCG_DEFAULT_NONE; 223 + mutex_unlock(&devcgroup_mutex); 224 + } 225 + 188 226 /* 189 227 * called from kernel/cgroup.c with cgroup_lock() held. 190 228 */ 191 229 static struct cgroup_subsys_state *devcgroup_css_alloc(struct cgroup *cgroup) 192 230 { 193 - struct dev_cgroup *dev_cgroup, *parent_dev_cgroup; 231 + struct dev_cgroup *dev_cgroup; 194 232 struct cgroup *parent_cgroup; 195 - int ret; 196 233 197 234 dev_cgroup = kzalloc(sizeof(*dev_cgroup), GFP_KERNEL); 198 235 if (!dev_cgroup) 199 236 return ERR_PTR(-ENOMEM); 200 237 INIT_LIST_HEAD(&dev_cgroup->exceptions); 238 + dev_cgroup->behavior = DEVCG_DEFAULT_NONE; 201 239 parent_cgroup = cgroup->parent; 202 - 203 - if (parent_cgroup == NULL) 204 - dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW; 205 - else { 206 - parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup); 207 - mutex_lock(&devcgroup_mutex); 208 - ret = dev_exceptions_copy(&dev_cgroup->exceptions, 209 - &parent_dev_cgroup->exceptions); 210 - dev_cgroup->behavior = parent_dev_cgroup->behavior; 211 - mutex_unlock(&devcgroup_mutex); 212 - if (ret) { 213 - kfree(dev_cgroup); 214 - return ERR_PTR(ret); 215 - } 216 - } 217 240 218 241 return &dev_cgroup->css; 219 242 } ··· 610 587 .can_attach = devcgroup_can_attach, 611 588 .css_alloc = devcgroup_css_alloc, 612 589 .css_free = devcgroup_css_free, 590 + .css_online = devcgroup_online, 591 + .css_offline = devcgroup_offline, 613 592 .subsys_id = devices_subsys_id, 614 593 .base_cftypes = dev_cgroup_files, 615 594