diff options
| author | Tejun Heo <tj@kernel.org> | 2014-05-16 13:22:48 -0400 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2014-05-16 13:22:48 -0400 |
| commit | d51f39b05ce0008118c45945e681b20484990571 (patch) | |
| tree | 5330c7169c843832515e6e1f9bb0d964d8eda299 | |
| parent | 5877019d97ab827b808e8759c71ef8d31490907a (diff) | |
cgroup: remove cgroup->parent
cgroup->parent is redundant as cgroup->self.parent can also be used to
determine the parent cgroup and we're moving towards using
cgroup_subsys_states as the fundamental structural blocks. This patch
introduces cgroup_parent() which follows cgroup->self.parent and
removes cgroup->parent.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
| -rw-r--r-- | include/linux/cgroup.h | 1 | ||||
| -rw-r--r-- | kernel/cgroup.c | 52 |
2 files changed, 30 insertions, 23 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 2549493d518d..fd538f4c2bb6 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
| @@ -178,7 +178,6 @@ struct cgroup { | |||
| 178 | struct list_head sibling; /* my parent's children */ | 178 | struct list_head sibling; /* my parent's children */ |
| 179 | struct list_head children; /* my children */ | 179 | struct list_head children; /* my children */ |
| 180 | 180 | ||
| 181 | struct cgroup *parent; /* my parent */ | ||
| 182 | struct kernfs_node *kn; /* cgroup kernfs entry */ | 181 | struct kernfs_node *kn; /* cgroup kernfs entry */ |
| 183 | struct kernfs_node *populated_kn; /* kn for "cgroup.subtree_populated" */ | 182 | struct kernfs_node *populated_kn; /* kn for "cgroup.subtree_populated" */ |
| 184 | 183 | ||
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 929bbbc539e9..8c67a739aea4 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -218,6 +218,15 @@ static void cgroup_idr_remove(struct idr *idr, int id) | |||
| 218 | spin_unlock_bh(&cgroup_idr_lock); | 218 | spin_unlock_bh(&cgroup_idr_lock); |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | static struct cgroup *cgroup_parent(struct cgroup *cgrp) | ||
| 222 | { | ||
| 223 | struct cgroup_subsys_state *parent_css = cgrp->self.parent; | ||
| 224 | |||
| 225 | if (parent_css) | ||
| 226 | return container_of(parent_css, struct cgroup, self); | ||
| 227 | return NULL; | ||
| 228 | } | ||
| 229 | |||
| 221 | /** | 230 | /** |
| 222 | * cgroup_css - obtain a cgroup's css for the specified subsystem | 231 | * cgroup_css - obtain a cgroup's css for the specified subsystem |
| 223 | * @cgrp: the cgroup of interest | 232 | * @cgrp: the cgroup of interest |
| @@ -260,9 +269,9 @@ static struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgrp, | |||
| 260 | if (!(cgrp->root->subsys_mask & (1 << ss->id))) | 269 | if (!(cgrp->root->subsys_mask & (1 << ss->id))) |
| 261 | return NULL; | 270 | return NULL; |
| 262 | 271 | ||
| 263 | while (cgrp->parent && | 272 | while (cgroup_parent(cgrp) && |
| 264 | !(cgrp->parent->child_subsys_mask & (1 << ss->id))) | 273 | !(cgroup_parent(cgrp)->child_subsys_mask & (1 << ss->id))) |
| 265 | cgrp = cgrp->parent; | 274 | cgrp = cgroup_parent(cgrp); |
| 266 | 275 | ||
| 267 | return cgroup_css(cgrp, ss); | 276 | return cgroup_css(cgrp, ss); |
| 268 | } | 277 | } |
| @@ -307,7 +316,7 @@ bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor) | |||
| 307 | while (cgrp) { | 316 | while (cgrp) { |
| 308 | if (cgrp == ancestor) | 317 | if (cgrp == ancestor) |
| 309 | return true; | 318 | return true; |
| 310 | cgrp = cgrp->parent; | 319 | cgrp = cgroup_parent(cgrp); |
| 311 | } | 320 | } |
| 312 | return false; | 321 | return false; |
| 313 | } | 322 | } |
| @@ -454,7 +463,7 @@ static void cgroup_update_populated(struct cgroup *cgrp, bool populated) | |||
| 454 | 463 | ||
| 455 | if (cgrp->populated_kn) | 464 | if (cgrp->populated_kn) |
| 456 | kernfs_notify(cgrp->populated_kn); | 465 | kernfs_notify(cgrp->populated_kn); |
| 457 | cgrp = cgrp->parent; | 466 | cgrp = cgroup_parent(cgrp); |
| 458 | } while (cgrp); | 467 | } while (cgrp); |
| 459 | } | 468 | } |
| 460 | 469 | ||
| @@ -2018,7 +2027,7 @@ static int cgroup_migrate_prepare_dst(struct cgroup *dst_cgrp, | |||
| 2018 | * Except for the root, child_subsys_mask must be zero for a cgroup | 2027 | * Except for the root, child_subsys_mask must be zero for a cgroup |
| 2019 | * with tasks so that child cgroups don't compete against tasks. | 2028 | * with tasks so that child cgroups don't compete against tasks. |
| 2020 | */ | 2029 | */ |
| 2021 | if (dst_cgrp && cgroup_on_dfl(dst_cgrp) && dst_cgrp->parent && | 2030 | if (dst_cgrp && cgroup_on_dfl(dst_cgrp) && cgroup_parent(dst_cgrp) && |
| 2022 | dst_cgrp->child_subsys_mask) | 2031 | dst_cgrp->child_subsys_mask) |
| 2023 | return -EBUSY; | 2032 | return -EBUSY; |
| 2024 | 2033 | ||
| @@ -2427,7 +2436,7 @@ static int cgroup_controllers_show(struct seq_file *seq, void *v) | |||
| 2427 | { | 2436 | { |
| 2428 | struct cgroup *cgrp = seq_css(seq)->cgroup; | 2437 | struct cgroup *cgrp = seq_css(seq)->cgroup; |
| 2429 | 2438 | ||
| 2430 | cgroup_print_ss_mask(seq, cgrp->parent->child_subsys_mask); | 2439 | cgroup_print_ss_mask(seq, cgroup_parent(cgrp)->child_subsys_mask); |
| 2431 | return 0; | 2440 | return 0; |
| 2432 | } | 2441 | } |
| 2433 | 2442 | ||
| @@ -2610,8 +2619,8 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, | |||
| 2610 | 2619 | ||
| 2611 | /* unavailable or not enabled on the parent? */ | 2620 | /* unavailable or not enabled on the parent? */ |
| 2612 | if (!(cgrp_dfl_root.subsys_mask & (1 << ssid)) || | 2621 | if (!(cgrp_dfl_root.subsys_mask & (1 << ssid)) || |
| 2613 | (cgrp->parent && | 2622 | (cgroup_parent(cgrp) && |
| 2614 | !(cgrp->parent->child_subsys_mask & (1 << ssid)))) { | 2623 | !(cgroup_parent(cgrp)->child_subsys_mask & (1 << ssid)))) { |
| 2615 | ret = -ENOENT; | 2624 | ret = -ENOENT; |
| 2616 | goto out_unlock; | 2625 | goto out_unlock; |
| 2617 | } | 2626 | } |
| @@ -2640,7 +2649,7 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, | |||
| 2640 | * Except for the root, child_subsys_mask must be zero for a cgroup | 2649 | * Except for the root, child_subsys_mask must be zero for a cgroup |
| 2641 | * with tasks so that child cgroups don't compete against tasks. | 2650 | * with tasks so that child cgroups don't compete against tasks. |
| 2642 | */ | 2651 | */ |
| 2643 | if (enable && cgrp->parent && !list_empty(&cgrp->cset_links)) { | 2652 | if (enable && cgroup_parent(cgrp) && !list_empty(&cgrp->cset_links)) { |
| 2644 | ret = -EBUSY; | 2653 | ret = -EBUSY; |
| 2645 | goto out_unlock; | 2654 | goto out_unlock; |
| 2646 | } | 2655 | } |
| @@ -2898,9 +2907,9 @@ static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[], | |||
| 2898 | continue; | 2907 | continue; |
| 2899 | if ((cft->flags & CFTYPE_INSANE) && cgroup_sane_behavior(cgrp)) | 2908 | if ((cft->flags & CFTYPE_INSANE) && cgroup_sane_behavior(cgrp)) |
| 2900 | continue; | 2909 | continue; |
| 2901 | if ((cft->flags & CFTYPE_NOT_ON_ROOT) && !cgrp->parent) | 2910 | if ((cft->flags & CFTYPE_NOT_ON_ROOT) && !cgroup_parent(cgrp)) |
| 2902 | continue; | 2911 | continue; |
| 2903 | if ((cft->flags & CFTYPE_ONLY_ON_ROOT) && cgrp->parent) | 2912 | if ((cft->flags & CFTYPE_ONLY_ON_ROOT) && cgroup_parent(cgrp)) |
| 2904 | continue; | 2913 | continue; |
| 2905 | 2914 | ||
| 2906 | if (is_add) { | 2915 | if (is_add) { |
| @@ -4092,14 +4101,14 @@ static void css_free_work_fn(struct work_struct *work) | |||
| 4092 | atomic_dec(&cgrp->root->nr_cgrps); | 4101 | atomic_dec(&cgrp->root->nr_cgrps); |
| 4093 | cgroup_pidlist_destroy_all(cgrp); | 4102 | cgroup_pidlist_destroy_all(cgrp); |
| 4094 | 4103 | ||
| 4095 | if (cgrp->parent) { | 4104 | if (cgroup_parent(cgrp)) { |
| 4096 | /* | 4105 | /* |
| 4097 | * We get a ref to the parent, and put the ref when | 4106 | * We get a ref to the parent, and put the ref when |
| 4098 | * this cgroup is being freed, so it's guaranteed | 4107 | * this cgroup is being freed, so it's guaranteed |
| 4099 | * that the parent won't be destroyed before its | 4108 | * that the parent won't be destroyed before its |
| 4100 | * children. | 4109 | * children. |
| 4101 | */ | 4110 | */ |
| 4102 | cgroup_put(cgrp->parent); | 4111 | cgroup_put(cgroup_parent(cgrp)); |
| 4103 | kernfs_put(cgrp->kn); | 4112 | kernfs_put(cgrp->kn); |
| 4104 | kfree(cgrp); | 4113 | kfree(cgrp); |
| 4105 | } else { | 4114 | } else { |
| @@ -4163,8 +4172,8 @@ static void init_and_link_css(struct cgroup_subsys_state *css, | |||
| 4163 | css->ss = ss; | 4172 | css->ss = ss; |
| 4164 | css->flags = 0; | 4173 | css->flags = 0; |
| 4165 | 4174 | ||
| 4166 | if (cgrp->parent) { | 4175 | if (cgroup_parent(cgrp)) { |
| 4167 | css->parent = cgroup_css(cgrp->parent, ss); | 4176 | css->parent = cgroup_css(cgroup_parent(cgrp), ss); |
| 4168 | css_get(css->parent); | 4177 | css_get(css->parent); |
| 4169 | } | 4178 | } |
| 4170 | 4179 | ||
| @@ -4218,7 +4227,7 @@ static void offline_css(struct cgroup_subsys_state *css) | |||
| 4218 | */ | 4227 | */ |
| 4219 | static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss) | 4228 | static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss) |
| 4220 | { | 4229 | { |
| 4221 | struct cgroup *parent = cgrp->parent; | 4230 | struct cgroup *parent = cgroup_parent(cgrp); |
| 4222 | struct cgroup_subsys_state *css; | 4231 | struct cgroup_subsys_state *css; |
| 4223 | int err; | 4232 | int err; |
| 4224 | 4233 | ||
| @@ -4251,7 +4260,7 @@ static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss) | |||
| 4251 | goto err_clear_dir; | 4260 | goto err_clear_dir; |
| 4252 | 4261 | ||
| 4253 | if (ss->broken_hierarchy && !ss->warned_broken_hierarchy && | 4262 | if (ss->broken_hierarchy && !ss->warned_broken_hierarchy && |
| 4254 | parent->parent) { | 4263 | cgroup_parent(parent)) { |
| 4255 | pr_warn("%s (%d) created nested cgroup for controller \"%s\" which has incomplete hierarchy support. Nested cgroups may change behavior in the future.\n", | 4264 | pr_warn("%s (%d) created nested cgroup for controller \"%s\" which has incomplete hierarchy support. Nested cgroups may change behavior in the future.\n", |
| 4256 | current->comm, current->pid, ss->name); | 4265 | current->comm, current->pid, ss->name); |
| 4257 | if (!strcmp(ss->name, "memory")) | 4266 | if (!strcmp(ss->name, "memory")) |
| @@ -4309,7 +4318,6 @@ static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, | |||
| 4309 | 4318 | ||
| 4310 | init_cgroup_housekeeping(cgrp); | 4319 | init_cgroup_housekeeping(cgrp); |
| 4311 | 4320 | ||
| 4312 | cgrp->parent = parent; | ||
| 4313 | cgrp->self.parent = &parent->self; | 4321 | cgrp->self.parent = &parent->self; |
| 4314 | cgrp->root = root; | 4322 | cgrp->root = root; |
| 4315 | 4323 | ||
| @@ -4336,7 +4344,7 @@ static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, | |||
| 4336 | cgrp->serial_nr = cgroup_serial_nr_next++; | 4344 | cgrp->serial_nr = cgroup_serial_nr_next++; |
| 4337 | 4345 | ||
| 4338 | /* allocation complete, commit to creation */ | 4346 | /* allocation complete, commit to creation */ |
| 4339 | list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children); | 4347 | list_add_tail_rcu(&cgrp->sibling, &cgroup_parent(cgrp)->children); |
| 4340 | atomic_inc(&root->nr_cgrps); | 4348 | atomic_inc(&root->nr_cgrps); |
| 4341 | cgroup_get(parent); | 4349 | cgroup_get(parent); |
| 4342 | 4350 | ||
| @@ -4531,8 +4539,8 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) | |||
| 4531 | */ | 4539 | */ |
| 4532 | kernfs_remove(cgrp->kn); | 4540 | kernfs_remove(cgrp->kn); |
| 4533 | 4541 | ||
| 4534 | set_bit(CGRP_RELEASABLE, &cgrp->parent->flags); | 4542 | set_bit(CGRP_RELEASABLE, &cgroup_parent(cgrp)->flags); |
| 4535 | check_for_release(cgrp->parent); | 4543 | check_for_release(cgroup_parent(cgrp)); |
| 4536 | 4544 | ||
| 4537 | /* put the base reference */ | 4545 | /* put the base reference */ |
| 4538 | percpu_ref_kill(&cgrp->self.refcnt); | 4546 | percpu_ref_kill(&cgrp->self.refcnt); |
