aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/cgroup.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/cgroup.h')
-rw-r--r--include/linux/cgroup.h58
1 files changed, 51 insertions, 7 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 0008dee66514..b8ad1ea99586 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -28,6 +28,7 @@ struct css_id;
28extern int cgroup_init_early(void); 28extern int cgroup_init_early(void);
29extern int cgroup_init(void); 29extern int cgroup_init(void);
30extern void cgroup_lock(void); 30extern void cgroup_lock(void);
31extern int cgroup_lock_is_held(void);
31extern bool cgroup_lock_live_group(struct cgroup *cgrp); 32extern bool cgroup_lock_live_group(struct cgroup *cgrp);
32extern void cgroup_unlock(void); 33extern void cgroup_unlock(void);
33extern void cgroup_fork(struct task_struct *p); 34extern void cgroup_fork(struct task_struct *p);
@@ -36,16 +37,24 @@ extern void cgroup_post_fork(struct task_struct *p);
36extern void cgroup_exit(struct task_struct *p, int run_callbacks); 37extern void cgroup_exit(struct task_struct *p, int run_callbacks);
37extern int cgroupstats_build(struct cgroupstats *stats, 38extern int cgroupstats_build(struct cgroupstats *stats,
38 struct dentry *dentry); 39 struct dentry *dentry);
40extern int cgroup_load_subsys(struct cgroup_subsys *ss);
41extern void cgroup_unload_subsys(struct cgroup_subsys *ss);
39 42
40extern const struct file_operations proc_cgroup_operations; 43extern const struct file_operations proc_cgroup_operations;
41 44
42/* Define the enumeration of all cgroup subsystems */ 45/* Define the enumeration of all builtin cgroup subsystems */
43#define SUBSYS(_x) _x ## _subsys_id, 46#define SUBSYS(_x) _x ## _subsys_id,
44enum cgroup_subsys_id { 47enum cgroup_subsys_id {
45#include <linux/cgroup_subsys.h> 48#include <linux/cgroup_subsys.h>
46 CGROUP_SUBSYS_COUNT 49 CGROUP_BUILTIN_SUBSYS_COUNT
47}; 50};
48#undef SUBSYS 51#undef SUBSYS
52/*
53 * This define indicates the maximum number of subsystems that can be loaded
54 * at once. We limit to this many since cgroupfs_root has subsys_bits to keep
55 * track of all of them.
56 */
57#define CGROUP_SUBSYS_COUNT (BITS_PER_BYTE*sizeof(unsigned long))
49 58
50/* Per-subsystem/per-cgroup state maintained by the system. */ 59/* Per-subsystem/per-cgroup state maintained by the system. */
51struct cgroup_subsys_state { 60struct cgroup_subsys_state {
@@ -75,6 +84,12 @@ enum {
75 CSS_REMOVED, /* This CSS is dead */ 84 CSS_REMOVED, /* This CSS is dead */
76}; 85};
77 86
87/* Caller must verify that the css is not for root cgroup */
88static inline void __css_get(struct cgroup_subsys_state *css, int count)
89{
90 atomic_add(count, &css->refcnt);
91}
92
78/* 93/*
79 * Call css_get() to hold a reference on the css; it can be used 94 * Call css_get() to hold a reference on the css; it can be used
80 * for a reference obtained via: 95 * for a reference obtained via:
@@ -86,7 +101,7 @@ static inline void css_get(struct cgroup_subsys_state *css)
86{ 101{
87 /* We don't need to reference count the root state */ 102 /* We don't need to reference count the root state */
88 if (!test_bit(CSS_ROOT, &css->flags)) 103 if (!test_bit(CSS_ROOT, &css->flags))
89 atomic_inc(&css->refcnt); 104 __css_get(css, 1);
90} 105}
91 106
92static inline bool css_is_removed(struct cgroup_subsys_state *css) 107static inline bool css_is_removed(struct cgroup_subsys_state *css)
@@ -117,11 +132,11 @@ static inline bool css_tryget(struct cgroup_subsys_state *css)
117 * css_get() or css_tryget() 132 * css_get() or css_tryget()
118 */ 133 */
119 134
120extern void __css_put(struct cgroup_subsys_state *css); 135extern void __css_put(struct cgroup_subsys_state *css, int count);
121static inline void css_put(struct cgroup_subsys_state *css) 136static inline void css_put(struct cgroup_subsys_state *css)
122{ 137{
123 if (!test_bit(CSS_ROOT, &css->flags)) 138 if (!test_bit(CSS_ROOT, &css->flags))
124 __css_put(css); 139 __css_put(css, 1);
125} 140}
126 141
127/* bits in struct cgroup flags field */ 142/* bits in struct cgroup flags field */
@@ -220,6 +235,10 @@ struct cgroup {
220 235
221 /* For RCU-protected deletion */ 236 /* For RCU-protected deletion */
222 struct rcu_head rcu_head; 237 struct rcu_head rcu_head;
238
239 /* List of events which userspace want to recieve */
240 struct list_head event_list;
241 spinlock_t event_list_lock;
223}; 242};
224 243
225/* 244/*
@@ -257,7 +276,8 @@ struct css_set {
257 /* 276 /*
258 * Set of subsystem states, one for each subsystem. This array 277 * Set of subsystem states, one for each subsystem. This array
259 * is immutable after creation apart from the init_css_set 278 * is immutable after creation apart from the init_css_set
260 * during subsystem registration (at boot time). 279 * during subsystem registration (at boot time) and modular subsystem
280 * loading/unloading.
261 */ 281 */
262 struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; 282 struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
263 283
@@ -362,6 +382,23 @@ struct cftype {
362 int (*trigger)(struct cgroup *cgrp, unsigned int event); 382 int (*trigger)(struct cgroup *cgrp, unsigned int event);
363 383
364 int (*release)(struct inode *inode, struct file *file); 384 int (*release)(struct inode *inode, struct file *file);
385
386 /*
387 * register_event() callback will be used to add new userspace
388 * waiter for changes related to the cftype. Implement it if
389 * you want to provide this functionality. Use eventfd_signal()
390 * on eventfd to send notification to userspace.
391 */
392 int (*register_event)(struct cgroup *cgrp, struct cftype *cft,
393 struct eventfd_ctx *eventfd, const char *args);
394 /*
395 * unregister_event() callback will be called when userspace
396 * closes the eventfd or on cgroup removing.
397 * This callback must be implemented, if you want provide
398 * notification functionality.
399 */
400 int (*unregister_event)(struct cgroup *cgrp, struct cftype *cft,
401 struct eventfd_ctx *eventfd);
365}; 402};
366 403
367struct cgroup_scanner { 404struct cgroup_scanner {
@@ -427,6 +464,8 @@ struct cgroup_subsys {
427 void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp); 464 void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
428 int (*can_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp, 465 int (*can_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
429 struct task_struct *tsk, bool threadgroup); 466 struct task_struct *tsk, bool threadgroup);
467 void (*cancel_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
468 struct task_struct *tsk, bool threadgroup);
430 void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp, 469 void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
431 struct cgroup *old_cgrp, struct task_struct *tsk, 470 struct cgroup *old_cgrp, struct task_struct *tsk,
432 bool threadgroup); 471 bool threadgroup);
@@ -471,6 +510,9 @@ struct cgroup_subsys {
471 /* used when use_id == true */ 510 /* used when use_id == true */
472 struct idr idr; 511 struct idr idr;
473 spinlock_t id_lock; 512 spinlock_t id_lock;
513
514 /* should be defined only by modular subsystems */
515 struct module *module;
474}; 516};
475 517
476#define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys; 518#define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys;
@@ -486,7 +528,9 @@ static inline struct cgroup_subsys_state *cgroup_subsys_state(
486static inline struct cgroup_subsys_state *task_subsys_state( 528static inline struct cgroup_subsys_state *task_subsys_state(
487 struct task_struct *task, int subsys_id) 529 struct task_struct *task, int subsys_id)
488{ 530{
489 return rcu_dereference(task->cgroups->subsys[subsys_id]); 531 return rcu_dereference_check(task->cgroups->subsys[subsys_id],
532 rcu_read_lock_held() ||
533 cgroup_lock_is_held());
490} 534}
491 535
492static inline struct cgroup* task_cgroup(struct task_struct *task, 536static inline struct cgroup* task_cgroup(struct task_struct *task,