diff options
-rw-r--r-- | include/linux/cgroup.h | 11 | ||||
-rw-r--r-- | kernel/cgroup.c | 9 |
2 files changed, 15 insertions, 5 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 5db8138a0482..b0d5f53ae5e1 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -225,6 +225,9 @@ struct cgroup { struct list_head pidlists; struct mutex pidlist_mutex; + /* dummy css with NULL ->ss, points back to this cgroup */ + struct cgroup_subsys_state dummy_css; + /* For css percpu_ref killing and RCU-protected deletion */ struct rcu_head rcu_head; struct work_struct destroy_work; @@ -668,7 +671,13 @@ struct cgroup_subsys_state *css_parent(struct cgroup_subsys_state *css) { struct cgroup *parent_cgrp = css->cgroup->parent; - return parent_cgrp ? parent_cgrp->subsys[css->ss->subsys_id] : NULL; + if (!parent_cgrp) + return NULL; + + if (css->ss) + return parent_cgrp->subsys[css->ss->subsys_id]; + else + return &parent_cgrp->dummy_css; } /** diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 583f8f66a7e1..c049992f1ffa 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1365,6 +1365,7 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp) INIT_LIST_HEAD(&cgrp->release_list); INIT_LIST_HEAD(&cgrp->pidlists); mutex_init(&cgrp->pidlist_mutex); + cgrp->dummy_css.cgroup = cgrp; INIT_LIST_HEAD(&cgrp->event_list); spin_lock_init(&cgrp->event_list_lock); simple_xattrs_init(&cgrp->xattrs); @@ -2285,7 +2286,7 @@ static struct cgroup_subsys_state *cgroup_file_css(struct cfent *cfe) if (cft->ss) return cgrp->subsys[cft->ss->subsys_id]; - return NULL; + return &cgrp->dummy_css; } /* A buffer size big enough for numbers or short strings */ @@ -2467,7 +2468,7 @@ static int cgroup_file_open(struct inode *inode, struct file *file) * unpinned either on open failure or release. This ensures that * @css stays alive for all file operations. */ - if (css && !css_tryget(css)) + if (css->ss && !css_tryget(css)) return -ENODEV; if (cft->read_map || cft->read_seq_string) { @@ -2477,7 +2478,7 @@ static int cgroup_file_open(struct inode *inode, struct file *file) err = cft->open(inode, file); } - if (css && err) + if (css->ss && err) css_put(css); return err; } @@ -2491,7 +2492,7 @@ static int cgroup_file_release(struct inode *inode, struct file *file) if (cft->release) ret = cft->release(inode, file); - if (css) + if (css->ss) css_put(css); return ret; } |