cgroup: implement CFTYPE_ONLY_ON_DFL
[firefly-linux-kernel-4.4.55.git] / include / linux / cgroup.h
index 8c283a910b91bcb81cfdecf03e7c9c338f3e8f59..43d1ed30bae3a76ce83b1007886d813c561419b1 100644 (file)
@@ -24,7 +24,7 @@
 
 #ifdef CONFIG_CGROUPS
 
-struct cgroupfs_root;
+struct cgroup_root;
 struct cgroup_subsys;
 struct inode;
 struct cgroup;
@@ -173,10 +173,13 @@ struct cgroup {
         */
        u64 serial_nr;
 
+       /* The bitmask of subsystems attached to this cgroup */
+       unsigned long subsys_mask;
+
        /* Private pointers for each registered subsystem */
        struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT];
 
-       struct cgroupfs_root *root;
+       struct cgroup_root *root;
 
        /*
         * List of cgrp_cset_links pointing at css_sets with tasks in this
@@ -208,7 +211,7 @@ struct cgroup {
 
 #define MAX_CGROUP_ROOT_NAMELEN 64
 
-/* cgroupfs_root->flags */
+/* cgroup_root->flags */
 enum {
        /*
         * Unfortunately, cgroup core and various controllers are riddled
@@ -247,6 +250,9 @@ enum {
         *
         * - "cgroup.clone_children" is removed.
         *
+        * - If mount is requested with sane_behavior but without any
+        *   subsystem, the default unified hierarchy is mounted.
+        *
         * - cpuset: tasks will be kept in empty cpusets when hotplug happens
         *   and take masks of ancestors with non-empty cpus/mems, instead of
         *   being moved to an ancestor.
@@ -269,21 +275,18 @@ enum {
 };
 
 /*
- * A cgroupfs_root represents the root of a cgroup hierarchy, and may be
+ * A cgroup_root represents the root of a cgroup hierarchy, and may be
  * associated with a kernfs_root to form an active hierarchy.  This is
  * internal to cgroup core.  Don't access directly from controllers.
  */
-struct cgroupfs_root {
+struct cgroup_root {
        struct kernfs_root *kf_root;
 
-       /* The bitmask of subsystems attached to this hierarchy */
-       unsigned long subsys_mask;
-
        /* Unique id for this hierarchy. */
        int hierarchy_id;
 
        /* The root cgroup.  Root is destroyed on its release. */
-       struct cgroup top_cgroup;
+       struct cgroup cgrp;
 
        /* Number of cgroups in the hierarchy, used only for /proc/cgroups */
        atomic_t nr_cgrps;
@@ -324,10 +327,14 @@ struct css_set {
        struct hlist_node hlist;
 
        /*
-        * List running through all tasks using this cgroup
-        * group. Protected by css_set_lock
+        * Lists running through all tasks using this cgroup group.
+        * mg_tasks lists tasks which belong to this cset but are in the
+        * process of being migrated out or in.  Protected by
+        * css_set_rwsem, but, during migration, once tasks are moved to
+        * mg_tasks, it can be read safely while holding cgroup_mutex.
         */
        struct list_head tasks;
+       struct list_head mg_tasks;
 
        /*
         * List of cgrp_cset_links pointing at cgroups referenced from this
@@ -342,6 +349,23 @@ struct css_set {
         */
        struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
 
+       /*
+        * List of csets participating in the on-going migration either as
+        * source or destination.  Protected by cgroup_mutex.
+        */
+       struct list_head mg_preload_node;
+       struct list_head mg_node;
+
+       /*
+        * If this cset is acting as the source of migration the following
+        * two fields are set.  mg_src_cgrp is the source cgroup of the
+        * on-going migration and mg_dst_cset is the destination cset the
+        * target tasks on this cset should be migrated to.  Protected by
+        * cgroup_mutex.
+        */
+       struct cgroup *mg_src_cgrp;
+       struct css_set *mg_dst_cset;
+
        /* For RCU-protected deletion */
        struct rcu_head rcu_head;
 };
@@ -360,6 +384,7 @@ enum {
        CFTYPE_NOT_ON_ROOT      = (1 << 1),     /* don't create on root cgrp */
        CFTYPE_INSANE           = (1 << 2),     /* don't create if sane_behavior */
        CFTYPE_NO_PREFIX        = (1 << 3),     /* (DON'T USE FOR NEW FILES) no subsys prefix */
+       CFTYPE_ONLY_ON_DFL      = (1 << 4),     /* only on default hierarchy */
 };
 
 #define MAX_CFTYPE_NAME                64
@@ -433,7 +458,7 @@ struct cftype {
         * Returns 0 or -ve error code.
         */
        int (*write_string)(struct cgroup_subsys_state *css, struct cftype *cft,
-                           const char *buffer);
+                           char *buffer);
        /*
         * trigger() callback can be used to get some kick from the
         * userspace, when the actual string written is not important
@@ -447,6 +472,13 @@ struct cftype {
 #endif
 };
 
+extern struct cgroup_root cgrp_dfl_root;
+
+static inline bool cgroup_on_dfl(const struct cgroup *cgrp)
+{
+       return cgrp->root == &cgrp_dfl_root;
+}
+
 /*
  * See the comment above CGRP_ROOT_SANE_BEHAVIOR for details.  This
  * function can be called as long as @cgrp is accessible.
@@ -487,39 +519,23 @@ struct cgroup_subsys_state *seq_css(struct seq_file *seq);
 
 static inline int cgroup_name(struct cgroup *cgrp, char *buf, size_t buflen)
 {
-       /* dummy_top doesn't have a kn associated */
-       if (cgrp->kn)
-               return kernfs_name(cgrp->kn, buf, buflen);
-       else
-               return strlcpy(buf, "/", buflen);
+       return kernfs_name(cgrp->kn, buf, buflen);
 }
 
 static inline char * __must_check cgroup_path(struct cgroup *cgrp, char *buf,
                                              size_t buflen)
 {
-       /* dummy_top doesn't have a kn associated */
-       if (cgrp->kn)
-               return kernfs_path(cgrp->kn, buf, buflen);
-       strlcpy(buf, "/", buflen);
-       return (buflen <= 2) ? NULL : buf;
+       return kernfs_path(cgrp->kn, buf, buflen);
 }
 
 static inline void pr_cont_cgroup_name(struct cgroup *cgrp)
 {
-       /* dummy_top doesn't have a kn associated */
-       if (cgrp->kn)
-               pr_cont_kernfs_name(cgrp->kn);
-       else
-               pr_cont("/");
+       pr_cont_kernfs_name(cgrp->kn);
 }
 
 static inline void pr_cont_cgroup_path(struct cgroup *cgrp)
 {
-       /* dummy_top doesn't have a kn associated */
-       if (cgrp->kn)
-               pr_cont_kernfs_path(cgrp->kn);
-       else
-               pr_cont("/");
+       pr_cont_kernfs_path(cgrp->kn);
 }
 
 char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
@@ -593,7 +609,7 @@ struct cgroup_subsys {
        const char *name;
 
        /* link to parent, protected by cgroup_lock() */
-       struct cgroupfs_root *root;
+       struct cgroup_root *root;
 
        /*
         * List of cftypes.  Each entry is the first entry of an array
@@ -637,10 +653,12 @@ struct cgroup_subsys_state *css_parent(struct cgroup_subsys_state *css)
  */
 #ifdef CONFIG_PROVE_RCU
 extern struct mutex cgroup_mutex;
+extern struct rw_semaphore css_set_rwsem;
 #define task_css_set_check(task, __c)                                  \
        rcu_dereference_check((task)->cgroups,                          \
-               lockdep_is_held(&(task)->alloc_lock) ||                 \
-               lockdep_is_held(&cgroup_mutex) || (__c))
+               lockdep_is_held(&cgroup_mutex) ||                       \
+               lockdep_is_held(&css_set_rwsem) ||                      \
+               ((task)->flags & PF_EXITING) || (__c))
 #else
 #define task_css_set_check(task, __c)                                  \
        rcu_dereference((task)->cgroups)