cgroup: implement CFTYPE_ONLY_ON_DFL
[firefly-linux-kernel-4.4.55.git] / include / linux / cgroup.h
index 298d616e8f40904b0428e0e35a675becab573037..43d1ed30bae3a76ce83b1007886d813c561419b1 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/rcupdate.h>
 #include <linux/rculist.h>
 #include <linux/cgroupstats.h>
-#include <linux/prio_heap.h>
 #include <linux/rwsem.h>
 #include <linux/idr.h>
 #include <linux/workqueue.h>
@@ -25,7 +24,7 @@
 
 #ifdef CONFIG_CGROUPS
 
-struct cgroupfs_root;
+struct cgroup_root;
 struct cgroup_subsys;
 struct inode;
 struct cgroup;
@@ -174,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
@@ -209,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
@@ -227,8 +229,8 @@ enum {
         *
         * The followings are the behaviors currently affected this flag.
         *
-        * - Mount options "noprefix" and "clone_children" are disallowed.
-        *   Also, cgroupfs file cgroup.clone_children is not created.
+        * - Mount options "noprefix", "xattr", "clone_children",
+        *   "release_agent" and "name" are disallowed.
         *
         * - When mounting an existing superblock, mount options should
         *   match.
@@ -246,7 +248,10 @@ enum {
         * - "release_agent" and "notify_on_release" are removed.
         *   Replacement notification mechanism will be implemented.
         *
-        * - "xattr" mount option is deprecated.  kernfs always enables it.
+        * - "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
@@ -267,26 +272,21 @@ enum {
 
        /* mount options live below bit 16 */
        CGRP_ROOT_OPTION_MASK   = (1 << 16) - 1,
-
-       CGRP_ROOT_SUBSYS_BOUND  = (1 << 16), /* subsystems finished binding */
 };
 
 /*
- * 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;
@@ -327,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
@@ -345,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;
 };
@@ -363,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
@@ -436,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
@@ -450,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.
@@ -459,6 +488,12 @@ static inline bool cgroup_sane_behavior(const struct cgroup *cgrp)
        return cgrp->root->flags & CGRP_ROOT_SANE_BEHAVIOR;
 }
 
+/* no synchronization, the result can only be used as a hint */
+static inline bool cgroup_has_tasks(struct cgroup *cgrp)
+{
+       return !list_empty(&cgrp->cset_links);
+}
+
 /* returns ino associated with a cgroup, 0 indicates unmounted root */
 static inline ino_t cgroup_ino(struct cgroup *cgrp)
 {
@@ -495,20 +530,12 @@ static inline char * __must_check cgroup_path(struct cgroup *cgrp, char *buf,
 
 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);
@@ -518,8 +545,6 @@ int cgroup_rm_cftypes(struct cftype *cfts);
 
 bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor);
 
-int cgroup_task_count(const struct cgroup *cgrp);
-
 /*
  * Control Group taskset, used to pass around set of tasks to cgroup_subsys
  * methods.
@@ -527,22 +552,15 @@ int cgroup_task_count(const struct cgroup *cgrp);
 struct cgroup_taskset;
 struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset);
 struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset);
-struct cgroup_subsys_state *cgroup_taskset_cur_css(struct cgroup_taskset *tset,
-                                                  int subsys_id);
-int cgroup_taskset_size(struct cgroup_taskset *tset);
 
 /**
  * cgroup_taskset_for_each - iterate cgroup_taskset
  * @task: the loop cursor
- * @skip_css: skip if task's css matches this, %NULL to iterate through all
  * @tset: taskset to iterate
  */
-#define cgroup_taskset_for_each(task, skip_css, tset)                  \
+#define cgroup_taskset_for_each(task, tset)                            \
        for ((task) = cgroup_taskset_first((tset)); (task);             \
-            (task) = cgroup_taskset_next((tset)))                      \
-               if (!(skip_css) ||                                      \
-                   cgroup_taskset_cur_css((tset),                      \
-                       (skip_css)->ss->id) != (skip_css))
+            (task) = cgroup_taskset_next((tset)))
 
 /*
  * Control Group subsystem type.
@@ -591,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
@@ -635,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)
@@ -811,11 +831,6 @@ void css_task_iter_start(struct cgroup_subsys_state *css,
 struct task_struct *css_task_iter_next(struct css_task_iter *it);
 void css_task_iter_end(struct css_task_iter *it);
 
-int css_scan_tasks(struct cgroup_subsys_state *css,
-                  bool (*test)(struct task_struct *, void *),
-                  void (*process)(struct task_struct *, void *),
-                  void *data, struct ptr_heap *heap);
-
 int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
 int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);