aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/cgroup.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-05 17:51:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-05 17:51:32 -0500
commit69234acee54407962a20bedf90ef9c96326994b5 (patch)
tree5e979b1a489d866691c2c65ac3f46b4f29feef68 /include/linux/cgroup.h
parent11eaaadb3ea376c6c194491c2e9bddd647f9d253 (diff)
parentd57456753787ab158f906f1f8eb58d54a2ccd9f4 (diff)
Merge branch 'for-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup updates from Tejun Heo: "The cgroup core saw several significant updates this cycle: - percpu_rwsem for threadgroup locking is reinstated. This was temporarily dropped due to down_write latency issues. Oleg's rework of percpu_rwsem which is scheduled to be merged in this merge window resolves the issue. - On the v2 hierarchy, when controllers are enabled and disabled, all operations are atomic and can fail and revert cleanly. This allows ->can_attach() failure which is necessary for cpu RT slices. - Tasks now stay associated with the original cgroups after exit until released. This allows tracking resources held by zombies (e.g. pids) and makes it easy to find out where zombies came from on the v2 hierarchy. The pids controller was broken before these changes as zombies escaped the limits; unfortunately, updating this behavior required too many invasive changes and I don't think it's a good idea to backport them, so the pids controller on 4.3, the first version which included the pids controller, will stay broken at least until I'm sure about the cgroup core changes. - Optimization of a couple common tests using static_key" * 'for-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: (38 commits) cgroup: fix race condition around termination check in css_task_iter_next() blkcg: don't create "io.stat" on the root cgroup cgroup: drop cgroup__DEVEL__legacy_files_on_dfl cgroup: replace error handling in cgroup_init() with WARN_ON()s cgroup: add cgroup_subsys->free() method and use it to fix pids controller cgroup: keep zombies associated with their original cgroups cgroup: make css_set_rwsem a spinlock and rename it to css_set_lock cgroup: don't hold css_set_rwsem across css task iteration cgroup: reorganize css_task_iter functions cgroup: factor out css_set_move_task() cgroup: keep css_set and task lists in chronological order cgroup: make cgroup_destroy_locked() test cgroup_is_populated() cgroup: make css_sets pin the associated cgroups cgroup: relocate cgroup_[try]get/put() cgroup: move check_for_release() invocation cgroup: replace cgroup_has_tasks() with cgroup_is_populated() cgroup: make cgroup->nr_populated count the number of populated css_sets cgroup: remove an unused parameter from cgroup_task_migrate() cgroup: fix too early usage of static_branch_disable() cgroup: make cgroup_update_dfl_csses() migrate all target processes atomically ...
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; }