diff options
Diffstat (limited to 'include/linux/cgroup.h')
-rw-r--r-- | include/linux/cgroup.h | 81 |
1 files changed, 55 insertions, 26 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 5a85b3415c1b..d3f5fba2c159 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/prio_heap.h> | 16 | #include <linux/prio_heap.h> |
17 | #include <linux/rwsem.h> | 17 | #include <linux/rwsem.h> |
18 | #include <linux/idr.h> | 18 | #include <linux/idr.h> |
19 | #include <linux/workqueue.h> | ||
19 | 20 | ||
20 | #ifdef CONFIG_CGROUPS | 21 | #ifdef CONFIG_CGROUPS |
21 | 22 | ||
@@ -76,12 +77,16 @@ struct cgroup_subsys_state { | |||
76 | unsigned long flags; | 77 | unsigned long flags; |
77 | /* ID for this css, if possible */ | 78 | /* ID for this css, if possible */ |
78 | struct css_id __rcu *id; | 79 | struct css_id __rcu *id; |
80 | |||
81 | /* Used to put @cgroup->dentry on the last css_put() */ | ||
82 | struct work_struct dput_work; | ||
79 | }; | 83 | }; |
80 | 84 | ||
81 | /* bits in struct cgroup_subsys_state flags field */ | 85 | /* bits in struct cgroup_subsys_state flags field */ |
82 | enum { | 86 | enum { |
83 | CSS_ROOT, /* This CSS is the root of the subsystem */ | 87 | CSS_ROOT, /* This CSS is the root of the subsystem */ |
84 | CSS_REMOVED, /* This CSS is dead */ | 88 | CSS_REMOVED, /* This CSS is dead */ |
89 | CSS_CLEAR_CSS_REFS, /* @ss->__DEPRECATED_clear_css_refs */ | ||
85 | }; | 90 | }; |
86 | 91 | ||
87 | /* Caller must verify that the css is not for root cgroup */ | 92 | /* Caller must verify that the css is not for root cgroup */ |
@@ -115,16 +120,12 @@ static inline bool css_is_removed(struct cgroup_subsys_state *css) | |||
115 | * the css has been destroyed. | 120 | * the css has been destroyed. |
116 | */ | 121 | */ |
117 | 122 | ||
123 | extern bool __css_tryget(struct cgroup_subsys_state *css); | ||
118 | static inline bool css_tryget(struct cgroup_subsys_state *css) | 124 | static inline bool css_tryget(struct cgroup_subsys_state *css) |
119 | { | 125 | { |
120 | if (test_bit(CSS_ROOT, &css->flags)) | 126 | if (test_bit(CSS_ROOT, &css->flags)) |
121 | return true; | 127 | return true; |
122 | while (!atomic_inc_not_zero(&css->refcnt)) { | 128 | return __css_tryget(css); |
123 | if (test_bit(CSS_REMOVED, &css->flags)) | ||
124 | return false; | ||
125 | cpu_relax(); | ||
126 | } | ||
127 | return true; | ||
128 | } | 129 | } |
129 | 130 | ||
130 | /* | 131 | /* |
@@ -132,11 +133,11 @@ static inline bool css_tryget(struct cgroup_subsys_state *css) | |||
132 | * css_get() or css_tryget() | 133 | * css_get() or css_tryget() |
133 | */ | 134 | */ |
134 | 135 | ||
135 | extern void __css_put(struct cgroup_subsys_state *css, int count); | 136 | extern void __css_put(struct cgroup_subsys_state *css); |
136 | static inline void css_put(struct cgroup_subsys_state *css) | 137 | static inline void css_put(struct cgroup_subsys_state *css) |
137 | { | 138 | { |
138 | if (!test_bit(CSS_ROOT, &css->flags)) | 139 | if (!test_bit(CSS_ROOT, &css->flags)) |
139 | __css_put(css, 1); | 140 | __css_put(css); |
140 | } | 141 | } |
141 | 142 | ||
142 | /* bits in struct cgroup flags field */ | 143 | /* bits in struct cgroup flags field */ |
@@ -175,6 +176,7 @@ struct cgroup { | |||
175 | */ | 176 | */ |
176 | struct list_head sibling; /* my parent's children */ | 177 | struct list_head sibling; /* my parent's children */ |
177 | struct list_head children; /* my children */ | 178 | struct list_head children; /* my children */ |
179 | struct list_head files; /* my files */ | ||
178 | 180 | ||
179 | struct cgroup *parent; /* my parent */ | 181 | struct cgroup *parent; /* my parent */ |
180 | struct dentry __rcu *dentry; /* cgroup fs entry, RCU protected */ | 182 | struct dentry __rcu *dentry; /* cgroup fs entry, RCU protected */ |
@@ -191,6 +193,9 @@ struct cgroup { | |||
191 | */ | 193 | */ |
192 | struct list_head css_sets; | 194 | struct list_head css_sets; |
193 | 195 | ||
196 | struct list_head allcg_node; /* cgroupfs_root->allcg_list */ | ||
197 | struct list_head cft_q_node; /* used during cftype add/rm */ | ||
198 | |||
194 | /* | 199 | /* |
195 | * Linked list running through all cgroups that can | 200 | * Linked list running through all cgroups that can |
196 | * potentially be reaped by the release agent. Protected by | 201 | * potentially be reaped by the release agent. Protected by |
@@ -275,11 +280,17 @@ struct cgroup_map_cb { | |||
275 | * - the 'cftype' of the file is file->f_dentry->d_fsdata | 280 | * - the 'cftype' of the file is file->f_dentry->d_fsdata |
276 | */ | 281 | */ |
277 | 282 | ||
278 | #define MAX_CFTYPE_NAME 64 | 283 | /* cftype->flags */ |
284 | #define CFTYPE_ONLY_ON_ROOT (1U << 0) /* only create on root cg */ | ||
285 | #define CFTYPE_NOT_ON_ROOT (1U << 1) /* don't create onp root cg */ | ||
286 | |||
287 | #define MAX_CFTYPE_NAME 64 | ||
288 | |||
279 | struct cftype { | 289 | struct cftype { |
280 | /* | 290 | /* |
281 | * By convention, the name should begin with the name of the | 291 | * By convention, the name should begin with the name of the |
282 | * subsystem, followed by a period | 292 | * subsystem, followed by a period. Zero length string indicates |
293 | * end of cftype array. | ||
283 | */ | 294 | */ |
284 | char name[MAX_CFTYPE_NAME]; | 295 | char name[MAX_CFTYPE_NAME]; |
285 | int private; | 296 | int private; |
@@ -295,6 +306,9 @@ struct cftype { | |||
295 | */ | 306 | */ |
296 | size_t max_write_len; | 307 | size_t max_write_len; |
297 | 308 | ||
309 | /* CFTYPE_* flags */ | ||
310 | unsigned int flags; | ||
311 | |||
298 | int (*open)(struct inode *inode, struct file *file); | 312 | int (*open)(struct inode *inode, struct file *file); |
299 | ssize_t (*read)(struct cgroup *cgrp, struct cftype *cft, | 313 | ssize_t (*read)(struct cgroup *cgrp, struct cftype *cft, |
300 | struct file *file, | 314 | struct file *file, |
@@ -373,6 +387,16 @@ struct cftype { | |||
373 | struct eventfd_ctx *eventfd); | 387 | struct eventfd_ctx *eventfd); |
374 | }; | 388 | }; |
375 | 389 | ||
390 | /* | ||
391 | * cftype_sets describe cftypes belonging to a subsystem and are chained at | ||
392 | * cgroup_subsys->cftsets. Each cftset points to an array of cftypes | ||
393 | * terminated by zero length name. | ||
394 | */ | ||
395 | struct cftype_set { | ||
396 | struct list_head node; /* chained at subsys->cftsets */ | ||
397 | const struct cftype *cfts; | ||
398 | }; | ||
399 | |||
376 | struct cgroup_scanner { | 400 | struct cgroup_scanner { |
377 | struct cgroup *cg; | 401 | struct cgroup *cg; |
378 | int (*test_task)(struct task_struct *p, struct cgroup_scanner *scan); | 402 | int (*test_task)(struct task_struct *p, struct cgroup_scanner *scan); |
@@ -382,21 +406,8 @@ struct cgroup_scanner { | |||
382 | void *data; | 406 | void *data; |
383 | }; | 407 | }; |
384 | 408 | ||
385 | /* | 409 | int cgroup_add_cftypes(struct cgroup_subsys *ss, const struct cftype *cfts); |
386 | * Add a new file to the given cgroup directory. Should only be | 410 | int cgroup_rm_cftypes(struct cgroup_subsys *ss, const struct cftype *cfts); |
387 | * called by subsystems from within a populate() method | ||
388 | */ | ||
389 | int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys, | ||
390 | const struct cftype *cft); | ||
391 | |||
392 | /* | ||
393 | * Add a set of new files to the given cgroup directory. Should | ||
394 | * only be called by subsystems from within a populate() method | ||
395 | */ | ||
396 | int cgroup_add_files(struct cgroup *cgrp, | ||
397 | struct cgroup_subsys *subsys, | ||
398 | const struct cftype cft[], | ||
399 | int count); | ||
400 | 411 | ||
401 | int cgroup_is_removed(const struct cgroup *cgrp); | 412 | int cgroup_is_removed(const struct cgroup *cgrp); |
402 | 413 | ||
@@ -461,7 +472,6 @@ struct cgroup_subsys { | |||
461 | void (*fork)(struct task_struct *task); | 472 | void (*fork)(struct task_struct *task); |
462 | void (*exit)(struct cgroup *cgrp, struct cgroup *old_cgrp, | 473 | void (*exit)(struct cgroup *cgrp, struct cgroup *old_cgrp, |
463 | struct task_struct *task); | 474 | struct task_struct *task); |
464 | int (*populate)(struct cgroup_subsys *ss, struct cgroup *cgrp); | ||
465 | void (*post_clone)(struct cgroup *cgrp); | 475 | void (*post_clone)(struct cgroup *cgrp); |
466 | void (*bind)(struct cgroup *root); | 476 | void (*bind)(struct cgroup *root); |
467 | 477 | ||
@@ -474,6 +484,18 @@ struct cgroup_subsys { | |||
474 | * (not available in early_init time.) | 484 | * (not available in early_init time.) |
475 | */ | 485 | */ |
476 | bool use_id; | 486 | bool use_id; |
487 | |||
488 | /* | ||
489 | * If %true, cgroup removal will try to clear css refs by retrying | ||
490 | * ss->pre_destroy() until there's no css ref left. This behavior | ||
491 | * is strictly for backward compatibility and will be removed as | ||
492 | * soon as the current user (memcg) is updated. | ||
493 | * | ||
494 | * If %false, ss->pre_destroy() can't fail and cgroup removal won't | ||
495 | * wait for css refs to drop to zero before proceeding. | ||
496 | */ | ||
497 | bool __DEPRECATED_clear_css_refs; | ||
498 | |||
477 | #define MAX_CGROUP_TYPE_NAMELEN 32 | 499 | #define MAX_CGROUP_TYPE_NAMELEN 32 |
478 | const char *name; | 500 | const char *name; |
479 | 501 | ||
@@ -500,6 +522,13 @@ struct cgroup_subsys { | |||
500 | struct idr idr; | 522 | struct idr idr; |
501 | spinlock_t id_lock; | 523 | spinlock_t id_lock; |
502 | 524 | ||
525 | /* list of cftype_sets */ | ||
526 | struct list_head cftsets; | ||
527 | |||
528 | /* base cftypes, automatically [de]registered with subsys itself */ | ||
529 | struct cftype *base_cftypes; | ||
530 | struct cftype_set base_cftset; | ||
531 | |||
503 | /* should be defined only by modular subsystems */ | 532 | /* should be defined only by modular subsystems */ |
504 | struct module *module; | 533 | struct module *module; |
505 | }; | 534 | }; |