diff options
| author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
|---|---|---|
| committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
| commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
| tree | 644b88f8a71896307d71438e9b3af49126ffb22b /include/linux/cgroup.h | |
| parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
| parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) | |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'include/linux/cgroup.h')
| -rw-r--r-- | include/linux/cgroup.h | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 0008dee66514..8f78073d7caa 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
| @@ -28,6 +28,7 @@ struct css_id; | |||
| 28 | extern int cgroup_init_early(void); | 28 | extern int cgroup_init_early(void); |
| 29 | extern int cgroup_init(void); | 29 | extern int cgroup_init(void); |
| 30 | extern void cgroup_lock(void); | 30 | extern void cgroup_lock(void); |
| 31 | extern int cgroup_lock_is_held(void); | ||
| 31 | extern bool cgroup_lock_live_group(struct cgroup *cgrp); | 32 | extern bool cgroup_lock_live_group(struct cgroup *cgrp); |
| 32 | extern void cgroup_unlock(void); | 33 | extern void cgroup_unlock(void); |
| 33 | extern void cgroup_fork(struct task_struct *p); | 34 | extern void cgroup_fork(struct task_struct *p); |
| @@ -36,16 +37,24 @@ extern void cgroup_post_fork(struct task_struct *p); | |||
| 36 | extern void cgroup_exit(struct task_struct *p, int run_callbacks); | 37 | extern void cgroup_exit(struct task_struct *p, int run_callbacks); |
| 37 | extern int cgroupstats_build(struct cgroupstats *stats, | 38 | extern int cgroupstats_build(struct cgroupstats *stats, |
| 38 | struct dentry *dentry); | 39 | struct dentry *dentry); |
| 40 | extern int cgroup_load_subsys(struct cgroup_subsys *ss); | ||
| 41 | extern void cgroup_unload_subsys(struct cgroup_subsys *ss); | ||
| 39 | 42 | ||
| 40 | extern const struct file_operations proc_cgroup_operations; | 43 | extern 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, |
| 44 | enum cgroup_subsys_id { | 47 | enum 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. */ |
| 51 | struct cgroup_subsys_state { | 60 | struct 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 */ | ||
| 88 | static 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 | ||
| 92 | static inline bool css_is_removed(struct cgroup_subsys_state *css) | 107 | static 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 | ||
| 120 | extern void __css_put(struct cgroup_subsys_state *css); | 135 | extern void __css_put(struct cgroup_subsys_state *css, int count); |
| 121 | static inline void css_put(struct cgroup_subsys_state *css) | 136 | static 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 | ||
| 367 | struct cgroup_scanner { | 404 | struct 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,10 @@ static inline struct cgroup_subsys_state *cgroup_subsys_state( | |||
| 486 | static inline struct cgroup_subsys_state *task_subsys_state( | 528 | static 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 | lockdep_is_held(&task->alloc_lock) || | ||
| 534 | cgroup_lock_is_held()); | ||
| 490 | } | 535 | } |
| 491 | 536 | ||
| 492 | static inline struct cgroup* task_cgroup(struct task_struct *task, | 537 | static inline struct cgroup* task_cgroup(struct task_struct *task, |
