|
@@ -4408,9 +4408,15 @@ static void css_release_work_fn(struct work_struct *work)
|
|
if (ss->css_released)
|
|
if (ss->css_released)
|
|
ss->css_released(css);
|
|
ss->css_released(css);
|
|
} else {
|
|
} else {
|
|
|
|
+ struct cgroup *tcgrp;
|
|
|
|
+
|
|
/* cgroup release path */
|
|
/* cgroup release path */
|
|
trace_cgroup_release(cgrp);
|
|
trace_cgroup_release(cgrp);
|
|
|
|
|
|
|
|
+ for (tcgrp = cgroup_parent(cgrp); tcgrp;
|
|
|
|
+ tcgrp = cgroup_parent(tcgrp))
|
|
|
|
+ tcgrp->nr_dying_descendants--;
|
|
|
|
+
|
|
cgroup_idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
|
|
cgroup_idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
|
|
cgrp->id = -1;
|
|
cgrp->id = -1;
|
|
|
|
|
|
@@ -4609,9 +4615,13 @@ static struct cgroup *cgroup_create(struct cgroup *parent)
|
|
cgrp->root = root;
|
|
cgrp->root = root;
|
|
cgrp->level = level;
|
|
cgrp->level = level;
|
|
|
|
|
|
- for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp))
|
|
|
|
|
|
+ for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) {
|
|
cgrp->ancestor_ids[tcgrp->level] = tcgrp->id;
|
|
cgrp->ancestor_ids[tcgrp->level] = tcgrp->id;
|
|
|
|
|
|
|
|
+ if (tcgrp != cgrp)
|
|
|
|
+ tcgrp->nr_descendants++;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (notify_on_release(parent))
|
|
if (notify_on_release(parent))
|
|
set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
|
|
set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
|
|
|
|
|
|
@@ -4817,7 +4827,7 @@ static void kill_css(struct cgroup_subsys_state *css)
|
|
static int cgroup_destroy_locked(struct cgroup *cgrp)
|
|
static int cgroup_destroy_locked(struct cgroup *cgrp)
|
|
__releases(&cgroup_mutex) __acquires(&cgroup_mutex)
|
|
__releases(&cgroup_mutex) __acquires(&cgroup_mutex)
|
|
{
|
|
{
|
|
- struct cgroup *parent = cgroup_parent(cgrp);
|
|
|
|
|
|
+ struct cgroup *tcgrp, *parent = cgroup_parent(cgrp);
|
|
struct cgroup_subsys_state *css;
|
|
struct cgroup_subsys_state *css;
|
|
struct cgrp_cset_link *link;
|
|
struct cgrp_cset_link *link;
|
|
int ssid;
|
|
int ssid;
|
|
@@ -4865,6 +4875,11 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
|
|
if (parent && cgroup_is_threaded(cgrp))
|
|
if (parent && cgroup_is_threaded(cgrp))
|
|
parent->nr_threaded_children--;
|
|
parent->nr_threaded_children--;
|
|
|
|
|
|
|
|
+ for (tcgrp = cgroup_parent(cgrp); tcgrp; tcgrp = cgroup_parent(tcgrp)) {
|
|
|
|
+ tcgrp->nr_descendants--;
|
|
|
|
+ tcgrp->nr_dying_descendants++;
|
|
|
|
+ }
|
|
|
|
+
|
|
cgroup1_check_for_release(cgroup_parent(cgrp));
|
|
cgroup1_check_for_release(cgroup_parent(cgrp));
|
|
|
|
|
|
/* put the base reference */
|
|
/* put the base reference */
|