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.h77
1 files changed, 55 insertions, 22 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 1164963c3a85..499900d0cee7 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -52,9 +52,9 @@ struct cgroup_subsys_state {
52 * hierarchy structure */ 52 * hierarchy structure */
53 struct cgroup *cgroup; 53 struct cgroup *cgroup;
54 54
55 /* State maintained by the cgroup system to allow 55 /* State maintained by the cgroup system to allow subsystems
56 * subsystems to be "busy". Should be accessed via css_get() 56 * to be "busy". Should be accessed via css_get(),
57 * and css_put() */ 57 * css_tryget() and and css_put(). */
58 58
59 atomic_t refcnt; 59 atomic_t refcnt;
60 60
@@ -64,11 +64,14 @@ struct cgroup_subsys_state {
64/* bits in struct cgroup_subsys_state flags field */ 64/* bits in struct cgroup_subsys_state flags field */
65enum { 65enum {
66 CSS_ROOT, /* This CSS is the root of the subsystem */ 66 CSS_ROOT, /* This CSS is the root of the subsystem */
67 CSS_REMOVED, /* This CSS is dead */
67}; 68};
68 69
69/* 70/*
70 * Call css_get() to hold a reference on the cgroup; 71 * Call css_get() to hold a reference on the css; it can be used
71 * 72 * for a reference obtained via:
73 * - an existing ref-counted reference to the css
74 * - task->cgroups for a locked task
72 */ 75 */
73 76
74static inline void css_get(struct cgroup_subsys_state *css) 77static inline void css_get(struct cgroup_subsys_state *css)
@@ -77,9 +80,33 @@ static inline void css_get(struct cgroup_subsys_state *css)
77 if (!test_bit(CSS_ROOT, &css->flags)) 80 if (!test_bit(CSS_ROOT, &css->flags))
78 atomic_inc(&css->refcnt); 81 atomic_inc(&css->refcnt);
79} 82}
83
84static inline bool css_is_removed(struct cgroup_subsys_state *css)
85{
86 return test_bit(CSS_REMOVED, &css->flags);
87}
88
89/*
90 * Call css_tryget() to take a reference on a css if your existing
91 * (known-valid) reference isn't already ref-counted. Returns false if
92 * the css has been destroyed.
93 */
94
95static inline bool css_tryget(struct cgroup_subsys_state *css)
96{
97 if (test_bit(CSS_ROOT, &css->flags))
98 return true;
99 while (!atomic_inc_not_zero(&css->refcnt)) {
100 if (test_bit(CSS_REMOVED, &css->flags))
101 return false;
102 cpu_relax();
103 }
104 return true;
105}
106
80/* 107/*
81 * css_put() should be called to release a reference taken by 108 * css_put() should be called to release a reference taken by
82 * css_get() 109 * css_get() or css_tryget()
83 */ 110 */
84 111
85extern void __css_put(struct cgroup_subsys_state *css); 112extern void __css_put(struct cgroup_subsys_state *css);
@@ -116,7 +143,7 @@ struct cgroup {
116 struct list_head children; /* my children */ 143 struct list_head children; /* my children */
117 144
118 struct cgroup *parent; /* my parent */ 145 struct cgroup *parent; /* my parent */
119 struct dentry *dentry; /* cgroup fs entry */ 146 struct dentry *dentry; /* cgroup fs entry, RCU protected */
120 147
121 /* Private pointers for each registered subsystem */ 148 /* Private pointers for each registered subsystem */
122 struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; 149 struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
@@ -145,6 +172,9 @@ struct cgroup {
145 int pids_use_count; 172 int pids_use_count;
146 /* Length of the current tasks_pids array */ 173 /* Length of the current tasks_pids array */
147 int pids_length; 174 int pids_length;
175
176 /* For RCU-protected deletion */
177 struct rcu_head rcu_head;
148}; 178};
149 179
150/* A css_set is a structure holding pointers to a set of 180/* A css_set is a structure holding pointers to a set of
@@ -329,13 +359,7 @@ struct cgroup_subsys {
329 struct cgroup *cgrp); 359 struct cgroup *cgrp);
330 void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp); 360 void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp);
331 void (*bind)(struct cgroup_subsys *ss, struct cgroup *root); 361 void (*bind)(struct cgroup_subsys *ss, struct cgroup *root);
332 /* 362
333 * This routine is called with the task_lock of mm->owner held
334 */
335 void (*mm_owner_changed)(struct cgroup_subsys *ss,
336 struct cgroup *old,
337 struct cgroup *new,
338 struct task_struct *p);
339 int subsys_id; 363 int subsys_id;
340 int active; 364 int active;
341 int disabled; 365 int disabled;
@@ -343,9 +367,24 @@ struct cgroup_subsys {
343#define MAX_CGROUP_TYPE_NAMELEN 32 367#define MAX_CGROUP_TYPE_NAMELEN 32
344 const char *name; 368 const char *name;
345 369
346 /* Protected by RCU */ 370 /*
347 struct cgroupfs_root *root; 371 * Protects sibling/children links of cgroups in this
372 * hierarchy, plus protects which hierarchy (or none) the
373 * subsystem is a part of (i.e. root/sibling). To avoid
374 * potential deadlocks, the following operations should not be
375 * undertaken while holding any hierarchy_mutex:
376 *
377 * - allocating memory
378 * - initiating hotplug events
379 */
380 struct mutex hierarchy_mutex;
381 struct lock_class_key subsys_key;
348 382
383 /*
384 * Link to parent, and list entry in parent's children.
385 * Protected by this->hierarchy_mutex and cgroup_lock()
386 */
387 struct cgroupfs_root *root;
349 struct list_head sibling; 388 struct list_head sibling;
350}; 389};
351 390
@@ -400,9 +439,6 @@ void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it);
400int cgroup_scan_tasks(struct cgroup_scanner *scan); 439int cgroup_scan_tasks(struct cgroup_scanner *scan);
401int cgroup_attach_task(struct cgroup *, struct task_struct *); 440int cgroup_attach_task(struct cgroup *, struct task_struct *);
402 441
403void cgroup_mm_owner_callbacks(struct task_struct *old,
404 struct task_struct *new);
405
406#else /* !CONFIG_CGROUPS */ 442#else /* !CONFIG_CGROUPS */
407 443
408static inline int cgroup_init_early(void) { return 0; } 444static inline int cgroup_init_early(void) { return 0; }
@@ -420,9 +456,6 @@ static inline int cgroupstats_build(struct cgroupstats *stats,
420 return -EINVAL; 456 return -EINVAL;
421} 457}
422 458
423static inline void cgroup_mm_owner_callbacks(struct task_struct *old,
424 struct task_struct *new) {}
425
426#endif /* !CONFIG_CGROUPS */ 459#endif /* !CONFIG_CGROUPS */
427 460
428#endif /* _LINUX_CGROUP_H */ 461#endif /* _LINUX_CGROUP_H */