diff options
Diffstat (limited to 'include/linux/cgroup.h')
-rw-r--r-- | include/linux/cgroup.h | 129 |
1 files changed, 66 insertions, 63 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index eb7ca55f72ef..22e3754f89c5 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -13,10 +13,10 @@ | |||
13 | #include <linux/nodemask.h> | 13 | #include <linux/nodemask.h> |
14 | #include <linux/rculist.h> | 14 | #include <linux/rculist.h> |
15 | #include <linux/cgroupstats.h> | 15 | #include <linux/cgroupstats.h> |
16 | #include <linux/rwsem.h> | ||
17 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
18 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
19 | #include <linux/kernfs.h> | 18 | #include <linux/kernfs.h> |
19 | #include <linux/jump_label.h> | ||
20 | 20 | ||
21 | #include <linux/cgroup-defs.h> | 21 | #include <linux/cgroup-defs.h> |
22 | 22 | ||
@@ -41,6 +41,10 @@ struct css_task_iter { | |||
41 | struct list_head *task_pos; | 41 | struct list_head *task_pos; |
42 | struct list_head *tasks_head; | 42 | struct list_head *tasks_head; |
43 | struct list_head *mg_tasks_head; | 43 | struct list_head *mg_tasks_head; |
44 | |||
45 | struct css_set *cur_cset; | ||
46 | struct task_struct *cur_task; | ||
47 | struct list_head iters_node; /* css_set->task_iters */ | ||
44 | }; | 48 | }; |
45 | 49 | ||
46 | extern struct cgroup_root cgrp_dfl_root; | 50 | extern struct cgroup_root cgrp_dfl_root; |
@@ -50,6 +54,26 @@ extern struct css_set init_css_set; | |||
50 | #include <linux/cgroup_subsys.h> | 54 | #include <linux/cgroup_subsys.h> |
51 | #undef SUBSYS | 55 | #undef SUBSYS |
52 | 56 | ||
57 | #define SUBSYS(_x) \ | ||
58 | extern struct static_key_true _x ## _cgrp_subsys_enabled_key; \ | ||
59 | extern struct static_key_true _x ## _cgrp_subsys_on_dfl_key; | ||
60 | #include <linux/cgroup_subsys.h> | ||
61 | #undef SUBSYS | ||
62 | |||
63 | /** | ||
64 | * cgroup_subsys_enabled - fast test on whether a subsys is enabled | ||
65 | * @ss: subsystem in question | ||
66 | */ | ||
67 | #define cgroup_subsys_enabled(ss) \ | ||
68 | static_branch_likely(&ss ## _enabled_key) | ||
69 | |||
70 | /** | ||
71 | * cgroup_subsys_on_dfl - fast test on whether a subsys is on default hierarchy | ||
72 | * @ss: subsystem in question | ||
73 | */ | ||
74 | #define cgroup_subsys_on_dfl(ss) \ | ||
75 | static_branch_likely(&ss ## _on_dfl_key) | ||
76 | |||
53 | bool css_has_online_children(struct cgroup_subsys_state *css); | 77 | bool css_has_online_children(struct cgroup_subsys_state *css); |
54 | struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss); | 78 | struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss); |
55 | struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgroup, | 79 | struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgroup, |
@@ -78,6 +102,7 @@ extern void cgroup_cancel_fork(struct task_struct *p, | |||
78 | extern void cgroup_post_fork(struct task_struct *p, | 102 | extern void cgroup_post_fork(struct task_struct *p, |
79 | void *old_ss_priv[CGROUP_CANFORK_COUNT]); | 103 | void *old_ss_priv[CGROUP_CANFORK_COUNT]); |
80 | void cgroup_exit(struct task_struct *p); | 104 | void cgroup_exit(struct task_struct *p); |
105 | void cgroup_free(struct task_struct *p); | ||
81 | 106 | ||
82 | int cgroup_init_early(void); | 107 | int cgroup_init_early(void); |
83 | int cgroup_init(void); | 108 | int cgroup_init(void); |
@@ -211,11 +236,33 @@ void css_task_iter_end(struct css_task_iter *it); | |||
211 | * cgroup_taskset_for_each - iterate cgroup_taskset | 236 | * cgroup_taskset_for_each - iterate cgroup_taskset |
212 | * @task: the loop cursor | 237 | * @task: the loop cursor |
213 | * @tset: taskset to iterate | 238 | * @tset: taskset to iterate |
239 | * | ||
240 | * @tset may contain multiple tasks and they may belong to multiple | ||
241 | * processes. When there are multiple tasks in @tset, if a task of a | ||
242 | * process is in @tset, all tasks of the process are in @tset. Also, all | ||
243 | * are guaranteed to share the same source and destination csses. | ||
244 | * | ||
245 | * Iteration is not in any specific order. | ||
214 | */ | 246 | */ |
215 | #define cgroup_taskset_for_each(task, tset) \ | 247 | #define cgroup_taskset_for_each(task, tset) \ |
216 | for ((task) = cgroup_taskset_first((tset)); (task); \ | 248 | for ((task) = cgroup_taskset_first((tset)); (task); \ |
217 | (task) = cgroup_taskset_next((tset))) | 249 | (task) = cgroup_taskset_next((tset))) |
218 | 250 | ||
251 | /** | ||
252 | * cgroup_taskset_for_each_leader - iterate group leaders in a cgroup_taskset | ||
253 | * @leader: the loop cursor | ||
254 | * @tset: takset to iterate | ||
255 | * | ||
256 | * Iterate threadgroup leaders of @tset. For single-task migrations, @tset | ||
257 | * may not contain any. | ||
258 | */ | ||
259 | #define cgroup_taskset_for_each_leader(leader, tset) \ | ||
260 | for ((leader) = cgroup_taskset_first((tset)); (leader); \ | ||
261 | (leader) = cgroup_taskset_next((tset))) \ | ||
262 | if ((leader) != (leader)->group_leader) \ | ||
263 | ; \ | ||
264 | else | ||
265 | |||
219 | /* | 266 | /* |
220 | * Inline functions. | 267 | * Inline functions. |
221 | */ | 268 | */ |
@@ -320,11 +367,11 @@ static inline void css_put_many(struct cgroup_subsys_state *css, unsigned int n) | |||
320 | */ | 367 | */ |
321 | #ifdef CONFIG_PROVE_RCU | 368 | #ifdef CONFIG_PROVE_RCU |
322 | extern struct mutex cgroup_mutex; | 369 | extern struct mutex cgroup_mutex; |
323 | extern struct rw_semaphore css_set_rwsem; | 370 | extern spinlock_t css_set_lock; |
324 | #define task_css_set_check(task, __c) \ | 371 | #define task_css_set_check(task, __c) \ |
325 | rcu_dereference_check((task)->cgroups, \ | 372 | rcu_dereference_check((task)->cgroups, \ |
326 | lockdep_is_held(&cgroup_mutex) || \ | 373 | lockdep_is_held(&cgroup_mutex) || \ |
327 | lockdep_is_held(&css_set_rwsem) || \ | 374 | lockdep_is_held(&css_set_lock) || \ |
328 | ((task)->flags & PF_EXITING) || (__c)) | 375 | ((task)->flags & PF_EXITING) || (__c)) |
329 | #else | 376 | #else |
330 | #define task_css_set_check(task, __c) \ | 377 | #define task_css_set_check(task, __c) \ |
@@ -412,68 +459,10 @@ static inline struct cgroup *task_cgroup(struct task_struct *task, | |||
412 | return task_css(task, subsys_id)->cgroup; | 459 | return task_css(task, subsys_id)->cgroup; |
413 | } | 460 | } |
414 | 461 | ||
415 | /** | ||
416 | * cgroup_on_dfl - test whether a cgroup is on the default hierarchy | ||
417 | * @cgrp: the cgroup of interest | ||
418 | * | ||
419 | * The default hierarchy is the v2 interface of cgroup and this function | ||
420 | * can be used to test whether a cgroup is on the default hierarchy for | ||
421 | * cases where a subsystem should behave differnetly depending on the | ||
422 | * interface version. | ||
423 | * | ||
424 | * The set of behaviors which change on the default hierarchy are still | ||
425 | * being determined and the mount option is prefixed with __DEVEL__. | ||
426 | * | ||
427 | * List of changed behaviors: | ||
428 | * | ||
429 | * - Mount options "noprefix", "xattr", "clone_children", "release_agent" | ||
430 | * and "name" are disallowed. | ||
431 | * | ||
432 | * - When mounting an existing superblock, mount options should match. | ||
433 | * | ||
434 | * - Remount is disallowed. | ||
435 | * | ||
436 | * - rename(2) is disallowed. | ||
437 | * | ||
438 | * - "tasks" is removed. Everything should be at process granularity. Use | ||
439 | * "cgroup.procs" instead. | ||
440 | * | ||
441 | * - "cgroup.procs" is not sorted. pids will be unique unless they got | ||
442 | * recycled inbetween reads. | ||
443 | * | ||
444 | * - "release_agent" and "notify_on_release" are removed. Replacement | ||
445 | * notification mechanism will be implemented. | ||
446 | * | ||
447 | * - "cgroup.clone_children" is removed. | ||
448 | * | ||
449 | * - "cgroup.subtree_populated" is available. Its value is 0 if the cgroup | ||
450 | * and its descendants contain no task; otherwise, 1. The file also | ||
451 | * generates kernfs notification which can be monitored through poll and | ||
452 | * [di]notify when the value of the file changes. | ||
453 | * | ||
454 | * - cpuset: tasks will be kept in empty cpusets when hotplug happens and | ||
455 | * take masks of ancestors with non-empty cpus/mems, instead of being | ||
456 | * moved to an ancestor. | ||
457 | * | ||
458 | * - cpuset: a task can be moved into an empty cpuset, and again it takes | ||
459 | * masks of ancestors. | ||
460 | * | ||
461 | * - memcg: use_hierarchy is on by default and the cgroup file for the flag | ||
462 | * is not created. | ||
463 | * | ||
464 | * - blkcg: blk-throttle becomes properly hierarchical. | ||
465 | * | ||
466 | * - debug: disallowed on the default hierarchy. | ||
467 | */ | ||
468 | static inline bool cgroup_on_dfl(const struct cgroup *cgrp) | ||
469 | { | ||
470 | return cgrp->root == &cgrp_dfl_root; | ||
471 | } | ||
472 | |||
473 | /* no synchronization, the result can only be used as a hint */ | 462 | /* no synchronization, the result can only be used as a hint */ |
474 | static inline bool cgroup_has_tasks(struct cgroup *cgrp) | 463 | static inline bool cgroup_is_populated(struct cgroup *cgrp) |
475 | { | 464 | { |
476 | return !list_empty(&cgrp->cset_links); | 465 | return cgrp->populated_cnt; |
477 | } | 466 | } |
478 | 467 | ||
479 | /* returns ino associated with a cgroup */ | 468 | /* returns ino associated with a cgroup */ |
@@ -527,6 +516,19 @@ static inline void pr_cont_cgroup_path(struct cgroup *cgrp) | |||
527 | pr_cont_kernfs_path(cgrp->kn); | 516 | pr_cont_kernfs_path(cgrp->kn); |
528 | } | 517 | } |
529 | 518 | ||
519 | /** | ||
520 | * cgroup_file_notify - generate a file modified event for a cgroup_file | ||
521 | * @cfile: target cgroup_file | ||
522 | * | ||
523 | * @cfile must have been obtained by setting cftype->file_offset. | ||
524 | */ | ||
525 | static inline void cgroup_file_notify(struct cgroup_file *cfile) | ||
526 | { | ||
527 | /* might not have been created due to one of the CFTYPE selector flags */ | ||
528 | if (cfile->kn) | ||
529 | kernfs_notify(cfile->kn); | ||
530 | } | ||
531 | |||
530 | #else /* !CONFIG_CGROUPS */ | 532 | #else /* !CONFIG_CGROUPS */ |
531 | 533 | ||
532 | struct cgroup_subsys_state; | 534 | struct cgroup_subsys_state; |
@@ -546,6 +548,7 @@ static inline void cgroup_cancel_fork(struct task_struct *p, | |||
546 | static inline void cgroup_post_fork(struct task_struct *p, | 548 | static inline void cgroup_post_fork(struct task_struct *p, |
547 | void *ss_priv[CGROUP_CANFORK_COUNT]) {} | 549 | void *ss_priv[CGROUP_CANFORK_COUNT]) {} |
548 | static inline void cgroup_exit(struct task_struct *p) {} | 550 | static inline void cgroup_exit(struct task_struct *p) {} |
551 | static inline void cgroup_free(struct task_struct *p) {} | ||
549 | 552 | ||
550 | static inline int cgroup_init_early(void) { return 0; } | 553 | static inline int cgroup_init_early(void) { return 0; } |
551 | static inline int cgroup_init(void) { return 0; } | 554 | static inline int cgroup_init(void) { return 0; } |