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.h129
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
46extern struct cgroup_root cgrp_dfl_root; 50extern 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
53bool css_has_online_children(struct cgroup_subsys_state *css); 77bool css_has_online_children(struct cgroup_subsys_state *css);
54struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss); 78struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss);
55struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgroup, 79struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgroup,
@@ -78,6 +102,7 @@ extern void cgroup_cancel_fork(struct task_struct *p,
78extern void cgroup_post_fork(struct task_struct *p, 102extern void cgroup_post_fork(struct task_struct *p,
79 void *old_ss_priv[CGROUP_CANFORK_COUNT]); 103 void *old_ss_priv[CGROUP_CANFORK_COUNT]);
80void cgroup_exit(struct task_struct *p); 104void cgroup_exit(struct task_struct *p);
105void cgroup_free(struct task_struct *p);
81 106
82int cgroup_init_early(void); 107int cgroup_init_early(void);
83int cgroup_init(void); 108int 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
322extern struct mutex cgroup_mutex; 369extern struct mutex cgroup_mutex;
323extern struct rw_semaphore css_set_rwsem; 370extern 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 */
468static 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 */
474static inline bool cgroup_has_tasks(struct cgroup *cgrp) 463static 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 */
525static 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
532struct cgroup_subsys_state; 534struct cgroup_subsys_state;
@@ -546,6 +548,7 @@ static inline void cgroup_cancel_fork(struct task_struct *p,
546static inline void cgroup_post_fork(struct task_struct *p, 548static inline void cgroup_post_fork(struct task_struct *p,
547 void *ss_priv[CGROUP_CANFORK_COUNT]) {} 549 void *ss_priv[CGROUP_CANFORK_COUNT]) {}
548static inline void cgroup_exit(struct task_struct *p) {} 550static inline void cgroup_exit(struct task_struct *p) {}
551static inline void cgroup_free(struct task_struct *p) {}
549 552
550static inline int cgroup_init_early(void) { return 0; } 553static inline int cgroup_init_early(void) { return 0; }
551static inline int cgroup_init(void) { return 0; } 554static inline int cgroup_init(void) { return 0; }