1#ifndef _LINUX_CGROUP_H
2#define _LINUX_CGROUP_H
3
4
5
6
7
8
9
10
11#include <linux/sched.h>
12#include <linux/kref.h>
13#include <linux/cpumask.h>
14#include <linux/nodemask.h>
15#include <linux/rcupdate.h>
16#include <linux/cgroupstats.h>
17#include <linux/prio_heap.h>
18
19#ifdef CONFIG_CGROUPS
20
21struct cgroupfs_root;
22struct cgroup_subsys;
23struct inode;
24
25extern int cgroup_init_early(void);
26extern int cgroup_init(void);
27extern void cgroup_init_smp(void);
28extern void cgroup_lock(void);
29extern void cgroup_unlock(void);
30extern void cgroup_fork(struct task_struct *p);
31extern void cgroup_fork_callbacks(struct task_struct *p);
32extern void cgroup_post_fork(struct task_struct *p);
33extern void cgroup_exit(struct task_struct *p, int run_callbacks);
34extern int cgroupstats_build(struct cgroupstats *stats,
35 struct dentry *dentry);
36
37extern struct file_operations proc_cgroup_operations;
38
39
40#define SUBSYS(_x) _x ## _subsys_id,
41enum cgroup_subsys_id {
42#include <linux/cgroup_subsys.h>
43 CGROUP_SUBSYS_COUNT
44};
45#undef SUBSYS
46
47
48struct cgroup_subsys_state {
49
50
51
52 struct cgroup *cgroup;
53
54
55
56
57
58 atomic_t refcnt;
59
60 unsigned long flags;
61};
62
63
64enum {
65 CSS_ROOT,
66};
67
68
69
70
71
72
73static inline void css_get(struct cgroup_subsys_state *css)
74{
75
76 if (!test_bit(CSS_ROOT, &css->flags))
77 atomic_inc(&css->refcnt);
78}
79
80
81
82
83
84extern void __css_put(struct cgroup_subsys_state *css);
85static inline void css_put(struct cgroup_subsys_state *css)
86{
87 if (!test_bit(CSS_ROOT, &css->flags))
88 __css_put(css);
89}
90
91
92enum {
93
94 CGRP_REMOVED,
95
96
97 CGRP_RELEASABLE,
98
99 CGRP_NOTIFY_ON_RELEASE,
100};
101
102struct cgroup {
103 unsigned long flags;
104
105
106
107
108 atomic_t count;
109
110
111
112
113
114 struct list_head sibling;
115 struct list_head children;
116
117 struct cgroup *parent;
118 struct dentry *dentry;
119
120
121 struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
122
123 struct cgroupfs_root *root;
124 struct cgroup *top_cgroup;
125
126
127
128
129
130 struct list_head css_sets;
131
132
133
134
135
136
137 struct list_head release_list;
138};
139
140
141
142
143
144
145
146
147struct css_set {
148
149
150 struct kref ref;
151
152
153
154
155
156 struct hlist_node hlist;
157
158
159
160
161
162 struct list_head tasks;
163
164
165
166
167
168
169 struct list_head cg_links;
170
171
172
173
174
175
176 struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
177};
178
179
180
181
182
183
184struct cgroup_map_cb {
185 int (*fill)(struct cgroup_map_cb *cb, const char *key, u64 value);
186 void *state;
187};
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202#define MAX_CFTYPE_NAME 64
203struct cftype {
204
205
206 char name[MAX_CFTYPE_NAME];
207 int private;
208 int (*open) (struct inode *inode, struct file *file);
209 ssize_t (*read) (struct cgroup *cgrp, struct cftype *cft,
210 struct file *file,
211 char __user *buf, size_t nbytes, loff_t *ppos);
212
213
214
215
216 u64 (*read_u64) (struct cgroup *cgrp, struct cftype *cft);
217
218
219
220 s64 (*read_s64) (struct cgroup *cgrp, struct cftype *cft);
221
222
223
224
225
226
227 int (*read_map) (struct cgroup *cont, struct cftype *cft,
228 struct cgroup_map_cb *cb);
229
230
231
232
233 int (*read_seq_string) (struct cgroup *cont, struct cftype *cft,
234 struct seq_file *m);
235
236 ssize_t (*write) (struct cgroup *cgrp, struct cftype *cft,
237 struct file *file,
238 const char __user *buf, size_t nbytes, loff_t *ppos);
239
240
241
242
243
244
245 int (*write_u64) (struct cgroup *cgrp, struct cftype *cft, u64 val);
246
247
248
249 int (*write_s64) (struct cgroup *cgrp, struct cftype *cft, s64 val);
250
251
252
253
254
255
256
257 int (*trigger)(struct cgroup *cgrp, unsigned int event);
258
259 int (*release) (struct inode *inode, struct file *file);
260};
261
262struct cgroup_scanner {
263 struct cgroup *cg;
264 int (*test_task)(struct task_struct *p, struct cgroup_scanner *scan);
265 void (*process_task)(struct task_struct *p,
266 struct cgroup_scanner *scan);
267 struct ptr_heap *heap;
268};
269
270
271
272int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys,
273 const struct cftype *cft);
274
275
276
277int cgroup_add_files(struct cgroup *cgrp,
278 struct cgroup_subsys *subsys,
279 const struct cftype cft[],
280 int count);
281
282int cgroup_is_removed(const struct cgroup *cgrp);
283
284int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen);
285
286int cgroup_task_count(const struct cgroup *cgrp);
287
288
289int cgroup_is_descendant(const struct cgroup *cgrp);
290
291
292
293struct cgroup_subsys {
294 struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss,
295 struct cgroup *cgrp);
296 void (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
297 void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
298 int (*can_attach)(struct cgroup_subsys *ss,
299 struct cgroup *cgrp, struct task_struct *tsk);
300 void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
301 struct cgroup *old_cgrp, struct task_struct *tsk);
302 void (*fork)(struct cgroup_subsys *ss, struct task_struct *task);
303 void (*exit)(struct cgroup_subsys *ss, struct task_struct *task);
304 int (*populate)(struct cgroup_subsys *ss,
305 struct cgroup *cgrp);
306 void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp);
307 void (*bind)(struct cgroup_subsys *ss, struct cgroup *root);
308
309
310
311 void (*mm_owner_changed)(struct cgroup_subsys *ss,
312 struct cgroup *old,
313 struct cgroup *new);
314 int subsys_id;
315 int active;
316 int disabled;
317 int early_init;
318#define MAX_CGROUP_TYPE_NAMELEN 32
319 const char *name;
320
321
322 struct cgroupfs_root *root;
323
324 struct list_head sibling;
325
326 void *private;
327};
328
329#define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys;
330#include <linux/cgroup_subsys.h>
331#undef SUBSYS
332
333static inline struct cgroup_subsys_state *cgroup_subsys_state(
334 struct cgroup *cgrp, int subsys_id)
335{
336 return cgrp->subsys[subsys_id];
337}
338
339static inline struct cgroup_subsys_state *task_subsys_state(
340 struct task_struct *task, int subsys_id)
341{
342 return rcu_dereference(task->cgroups->subsys[subsys_id]);
343}
344
345static inline struct cgroup* task_cgroup(struct task_struct *task,
346 int subsys_id)
347{
348 return task_subsys_state(task, subsys_id)->cgroup;
349}
350
351int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *ss);
352
353
354struct cgroup_iter {
355 struct list_head *cg_link;
356 struct list_head *task;
357};
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372void cgroup_iter_start(struct cgroup *cgrp, struct cgroup_iter *it);
373struct task_struct *cgroup_iter_next(struct cgroup *cgrp,
374 struct cgroup_iter *it);
375void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it);
376int cgroup_scan_tasks(struct cgroup_scanner *scan);
377int cgroup_attach_task(struct cgroup *, struct task_struct *);
378
379#else
380
381static inline int cgroup_init_early(void) { return 0; }
382static inline int cgroup_init(void) { return 0; }
383static inline void cgroup_init_smp(void) {}
384static inline void cgroup_fork(struct task_struct *p) {}
385static inline void cgroup_fork_callbacks(struct task_struct *p) {}
386static inline void cgroup_post_fork(struct task_struct *p) {}
387static inline void cgroup_exit(struct task_struct *p, int callbacks) {}
388
389static inline void cgroup_lock(void) {}
390static inline void cgroup_unlock(void) {}
391static inline int cgroupstats_build(struct cgroupstats *stats,
392 struct dentry *dentry)
393{
394 return -EINVAL;
395}
396
397#endif
398
399#ifdef CONFIG_MM_OWNER
400extern void
401cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new);
402#else
403static inline void
404cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new)
405{
406}
407#endif
408#endif
409