]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/linux/cgroup.h
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.25
[linux-2.6-omap-h63xx.git] / include / linux / cgroup.h
index a9553568118fed713c32bf3256fdecafd0d8b603..028ba3b523b1b8a3a8cdeea0ad745552ae84a8cd 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/cpumask.h>
 #include <linux/nodemask.h>
 #include <linux/rcupdate.h>
+#include <linux/cgroupstats.h>
+#include <linux/prio_heap.h>
 
 #ifdef CONFIG_CGROUPS
 
@@ -27,10 +29,21 @@ extern void cgroup_lock(void);
 extern void cgroup_unlock(void);
 extern void cgroup_fork(struct task_struct *p);
 extern void cgroup_fork_callbacks(struct task_struct *p);
+extern void cgroup_post_fork(struct task_struct *p);
 extern void cgroup_exit(struct task_struct *p, int run_callbacks);
+extern int cgroupstats_build(struct cgroupstats *stats,
+                               struct dentry *dentry);
 
 extern struct file_operations proc_cgroup_operations;
 
+/* Define the enumeration of all cgroup subsystems */
+#define SUBSYS(_x) _x ## _subsys_id,
+enum cgroup_subsys_id {
+#include <linux/cgroup_subsys.h>
+       CGROUP_SUBSYS_COUNT
+};
+#undef SUBSYS
+
 /* Per-subsystem/per-cgroup state maintained by the system. */
 struct cgroup_subsys_state {
        /* The cgroup that this subsystem is attached to. Useful
@@ -68,10 +81,11 @@ static inline void css_get(struct cgroup_subsys_state *css)
  * css_get()
  */
 
+extern void __css_put(struct cgroup_subsys_state *css);
 static inline void css_put(struct cgroup_subsys_state *css)
 {
        if (!test_bit(CSS_ROOT, &css->flags))
-               atomic_dec(&css->refcnt);
+               __css_put(css);
 }
 
 struct cgroup {
@@ -97,6 +111,59 @@ struct cgroup {
 
        struct cgroupfs_root *root;
        struct cgroup *top_cgroup;
+
+       /*
+        * List of cg_cgroup_links pointing at css_sets with
+        * tasks in this cgroup. Protected by css_set_lock
+        */
+       struct list_head css_sets;
+
+       /*
+        * Linked list running through all cgroups that can
+        * potentially be reaped by the release agent. Protected by
+        * release_list_lock
+        */
+       struct list_head release_list;
+};
+
+/* A css_set is a structure holding pointers to a set of
+ * cgroup_subsys_state objects. This saves space in the task struct
+ * object and speeds up fork()/exit(), since a single inc/dec and a
+ * list_add()/del() can bump the reference count on the entire
+ * cgroup set for a task.
+ */
+
+struct css_set {
+
+       /* Reference count */
+       struct kref ref;
+
+       /*
+        * List running through all cgroup groups. Protected by
+        * css_set_lock
+        */
+       struct list_head list;
+
+       /*
+        * List running through all tasks using this cgroup
+        * group. Protected by css_set_lock
+        */
+       struct list_head tasks;
+
+       /*
+        * List of cg_cgroup_link objects on link chains from
+        * cgroups referenced from this css_set. Protected by
+        * css_set_lock
+        */
+       struct list_head cg_links;
+
+       /*
+        * Set of subsystem states, one for each subsystem. This array
+        * is immutable after creation apart from the init_css_set
+        * during subsystem registration (at boot time).
+        */
+       struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
+
 };
 
 /* struct cftype:
@@ -108,7 +175,7 @@ struct cgroup {
  *
  *
  * When reading/writing to a file:
- *     - the cgroup to use in file->f_dentry->d_parent->d_fsdata
+ *     - the cgroup to use is file->f_dentry->d_parent->d_fsdata
  *     - the 'cftype' of the file is file->f_dentry->d_fsdata
  */
 
@@ -119,15 +186,15 @@ struct cftype {
        char name[MAX_CFTYPE_NAME];
        int private;
        int (*open) (struct inode *inode, struct file *file);
-       ssize_t (*read) (struct cgroup *cont, struct cftype *cft,
+       ssize_t (*read) (struct cgroup *cgrp, struct cftype *cft,
                         struct file *file,
                         char __user *buf, size_t nbytes, loff_t *ppos);
        /*
         * read_uint() is a shortcut for the common case of returning a
         * single integer. Use it in place of read()
         */
-       u64 (*read_uint) (struct cgroup *cont, struct cftype *cft);
-       ssize_t (*write) (struct cgroup *cont, struct cftype *cft,
+       u64 (*read_uint) (struct cgroup *cgrp, struct cftype *cft);
+       ssize_t (*write) (struct cgroup *cgrp, struct cftype *cft,
                          struct file *file,
                          const char __user *buf, size_t nbytes, loff_t *ppos);
 
@@ -136,55 +203,56 @@ struct cftype {
         * a single integer (as parsed by simple_strtoull) from
         * userspace. Use in place of write(); return 0 or error.
         */
-       int (*write_uint) (struct cgroup *cont, struct cftype *cft, u64 val);
+       int (*write_uint) (struct cgroup *cgrp, struct cftype *cft, u64 val);
 
        int (*release) (struct inode *inode, struct file *file);
 };
 
+struct cgroup_scanner {
+       struct cgroup *cg;
+       int (*test_task)(struct task_struct *p, struct cgroup_scanner *scan);
+       void (*process_task)(struct task_struct *p,
+                       struct cgroup_scanner *scan);
+       struct ptr_heap *heap;
+};
+
 /* Add a new file to the given cgroup directory. Should only be
  * called by subsystems from within a populate() method */
-int cgroup_add_file(struct cgroup *cont, struct cgroup_subsys *subsys,
+int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys,
                       const struct cftype *cft);
 
 /* Add a set of new files to the given cgroup directory. Should
  * only be called by subsystems from within a populate() method */
-int cgroup_add_files(struct cgroup *cont,
+int cgroup_add_files(struct cgroup *cgrp,
                        struct cgroup_subsys *subsys,
                        const struct cftype cft[],
                        int count);
 
-int cgroup_is_removed(const struct cgroup *cont);
+int cgroup_is_removed(const struct cgroup *cgrp);
 
-int cgroup_path(const struct cgroup *cont, char *buf, int buflen);
+int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen);
 
-int __cgroup_task_count(const struct cgroup *cont);
-static inline int cgroup_task_count(const struct cgroup *cont)
-{
-       int task_count;
-       rcu_read_lock();
-       task_count = __cgroup_task_count(cont);
-       rcu_read_unlock();
-       return task_count;
-}
+int cgroup_task_count(const struct cgroup *cgrp);
 
 /* Return true if the cgroup is a descendant of the current cgroup */
-int cgroup_is_descendant(const struct cgroup *cont);
+int cgroup_is_descendant(const struct cgroup *cgrp);
 
 /* Control Group subsystem type. See Documentation/cgroups.txt for details */
 
 struct cgroup_subsys {
        struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss,
-                                                 struct cgroup *cont);
-       void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cont);
+                                                 struct cgroup *cgrp);
+       void (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
+       void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
        int (*can_attach)(struct cgroup_subsys *ss,
-                         struct cgroup *cont, struct task_struct *tsk);
-       void (*attach)(struct cgroup_subsys *ss, struct cgroup *cont,
-                       struct cgroup *old_cont, struct task_struct *tsk);
+                         struct cgroup *cgrp, struct task_struct *tsk);
+       void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
+                       struct cgroup *old_cgrp, struct task_struct *tsk);
        void (*fork)(struct cgroup_subsys *ss, struct task_struct *task);
        void (*exit)(struct cgroup_subsys *ss, struct task_struct *task);
        int (*populate)(struct cgroup_subsys *ss,
-                       struct cgroup *cont);
-       void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cont);
+                       struct cgroup *cgrp);
+       void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp);
        void (*bind)(struct cgroup_subsys *ss, struct cgroup *root);
        int subsys_id;
        int active;
@@ -205,15 +273,15 @@ struct cgroup_subsys {
 #undef SUBSYS
 
 static inline struct cgroup_subsys_state *cgroup_subsys_state(
-       struct cgroup *cont, int subsys_id)
+       struct cgroup *cgrp, int subsys_id)
 {
-       return cont->subsys[subsys_id];
+       return cgrp->subsys[subsys_id];
 }
 
 static inline struct cgroup_subsys_state *task_subsys_state(
        struct task_struct *task, int subsys_id)
 {
-       return rcu_dereference(task->cgroups.subsys[subsys_id]);
+       return rcu_dereference(task->cgroups->subsys[subsys_id]);
 }
 
 static inline struct cgroup* task_cgroup(struct task_struct *task,
@@ -222,10 +290,34 @@ static inline struct cgroup* task_cgroup(struct task_struct *task,
        return task_subsys_state(task, subsys_id)->cgroup;
 }
 
-int cgroup_path(const struct cgroup *cont, char *buf, int buflen);
-
 int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *ss);
 
+/* A cgroup_iter should be treated as an opaque object */
+struct cgroup_iter {
+       struct list_head *cg_link;
+       struct list_head *task;
+};
+
+/* To iterate across the tasks in a cgroup:
+ *
+ * 1) call cgroup_iter_start to intialize an iterator
+ *
+ * 2) call cgroup_iter_next() to retrieve member tasks until it
+ *    returns NULL or until you want to end the iteration
+ *
+ * 3) call cgroup_iter_end() to destroy the iterator.
+ *
+ * Or, call cgroup_scan_tasks() to iterate through every task in a cpuset.
+ *    - cgroup_scan_tasks() holds the css_set_lock when calling the test_task()
+ *      callback, but not while calling the process_task() callback.
+ */
+void cgroup_iter_start(struct cgroup *cgrp, struct cgroup_iter *it);
+struct task_struct *cgroup_iter_next(struct cgroup *cgrp,
+                                       struct cgroup_iter *it);
+void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it);
+int cgroup_scan_tasks(struct cgroup_scanner *scan);
+int cgroup_attach_task(struct cgroup *, struct task_struct *);
+
 #else /* !CONFIG_CGROUPS */
 
 static inline int cgroup_init_early(void) { return 0; }
@@ -233,10 +325,16 @@ static inline int cgroup_init(void) { return 0; }
 static inline void cgroup_init_smp(void) {}
 static inline void cgroup_fork(struct task_struct *p) {}
 static inline void cgroup_fork_callbacks(struct task_struct *p) {}
+static inline void cgroup_post_fork(struct task_struct *p) {}
 static inline void cgroup_exit(struct task_struct *p, int callbacks) {}
 
 static inline void cgroup_lock(void) {}
 static inline void cgroup_unlock(void) {}
+static inline int cgroupstats_build(struct cgroupstats *stats,
+                                       struct dentry *dentry)
+{
+       return -EINVAL;
+}
 
 #endif /* !CONFIG_CGROUPS */