diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-10 22:45:50 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-10 22:45:50 -0500 |
commit | e8b722f487589a1f60ca27adc695494f188d404e (patch) | |
tree | be3897dceb9b7c0949a8917ab11eea2752375e3b /include/linux/cgroup.h | |
parent | 01d07820a0df6b6134c1bb75b1e84c9d0cdab3be (diff) | |
parent | c59765042f53a79a7a65585042ff463b69cb248c (diff) |
Merge commit 'v2.6.29-rc1' into irq/urgent
Diffstat (limited to 'include/linux/cgroup.h')
-rw-r--r-- | include/linux/cgroup.h | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 08b78c09b09a..e267e62827bb 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 */ |
65 | enum { | 65 | enum { |
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 | ||
74 | static inline void css_get(struct cgroup_subsys_state *css) | 77 | static inline void css_get(struct cgroup_subsys_state *css) |
@@ -77,9 +80,32 @@ 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 | |||
84 | static 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 | |||
95 | static 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 | } | ||
103 | return true; | ||
104 | } | ||
105 | |||
80 | /* | 106 | /* |
81 | * css_put() should be called to release a reference taken by | 107 | * css_put() should be called to release a reference taken by |
82 | * css_get() | 108 | * css_get() or css_tryget() |
83 | */ | 109 | */ |
84 | 110 | ||
85 | extern void __css_put(struct cgroup_subsys_state *css); | 111 | extern void __css_put(struct cgroup_subsys_state *css); |
@@ -116,7 +142,7 @@ struct cgroup { | |||
116 | struct list_head children; /* my children */ | 142 | struct list_head children; /* my children */ |
117 | 143 | ||
118 | struct cgroup *parent; /* my parent */ | 144 | struct cgroup *parent; /* my parent */ |
119 | struct dentry *dentry; /* cgroup fs entry */ | 145 | struct dentry *dentry; /* cgroup fs entry, RCU protected */ |
120 | 146 | ||
121 | /* Private pointers for each registered subsystem */ | 147 | /* Private pointers for each registered subsystem */ |
122 | struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; | 148 | struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; |
@@ -145,6 +171,9 @@ struct cgroup { | |||
145 | int pids_use_count; | 171 | int pids_use_count; |
146 | /* Length of the current tasks_pids array */ | 172 | /* Length of the current tasks_pids array */ |
147 | int pids_length; | 173 | int pids_length; |
174 | |||
175 | /* For RCU-protected deletion */ | ||
176 | struct rcu_head rcu_head; | ||
148 | }; | 177 | }; |
149 | 178 | ||
150 | /* A css_set is a structure holding pointers to a set of | 179 | /* A css_set is a structure holding pointers to a set of |
@@ -337,9 +366,23 @@ struct cgroup_subsys { | |||
337 | #define MAX_CGROUP_TYPE_NAMELEN 32 | 366 | #define MAX_CGROUP_TYPE_NAMELEN 32 |
338 | const char *name; | 367 | const char *name; |
339 | 368 | ||
340 | /* Protected by RCU */ | 369 | /* |
341 | struct cgroupfs_root *root; | 370 | * Protects sibling/children links of cgroups in this |
371 | * hierarchy, plus protects which hierarchy (or none) the | ||
372 | * subsystem is a part of (i.e. root/sibling). To avoid | ||
373 | * potential deadlocks, the following operations should not be | ||
374 | * undertaken while holding any hierarchy_mutex: | ||
375 | * | ||
376 | * - allocating memory | ||
377 | * - initiating hotplug events | ||
378 | */ | ||
379 | struct mutex hierarchy_mutex; | ||
342 | 380 | ||
381 | /* | ||
382 | * Link to parent, and list entry in parent's children. | ||
383 | * Protected by this->hierarchy_mutex and cgroup_lock() | ||
384 | */ | ||
385 | struct cgroupfs_root *root; | ||
343 | struct list_head sibling; | 386 | struct list_head sibling; |
344 | }; | 387 | }; |
345 | 388 | ||