cgroup: add cgroup->dummy_css
authorTejun Heo <tj@kernel.org>
Fri, 9 Aug 2013 00:11:24 +0000 (20:11 -0400)
committerTejun Heo <tj@kernel.org>
Fri, 9 Aug 2013 00:11:24 +0000 (20:11 -0400)
cgroup subsystem API is being converted to use css
(cgroup_subsys_state) as the main handle, which makes things a bit
awkward for subsystem agnostic core features - the "cgroup.*"
interface files and various iterations - a bit awkward as they don't
have a css to use.

This patch adds cgroup->dummy_css which has NULL ->ss and whose only
role is pointing back to the cgroup.  This will be used to support
subsystem agnostic features on the coming css based API.

css_parent() is updated to handle dummy_css's.  Note that css will
soon grow its own ->parent field and css_parent() will be made
trivial.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
include/linux/cgroup.h
kernel/cgroup.c

index 5db8138a04820a387a2b7a42fed8f69d64193201..b0d5f53ae5e1208423e81bf6164963d9da25580d 100644 (file)
@@ -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;
 }
 
 /**
index 583f8f66a7e1b510141716b2c5d85c68f115ebf5..c049992f1ffa06e271dc7cb74c938c15268e1582 100644 (file)
@@ -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;
 }