1244951Sadrian/* SPDX-License-Identifier: GPL-2.0 */ 2244951Sadrian#ifndef __CGROUP_INTERNAL_H 3244951Sadrian#define __CGROUP_INTERNAL_H 4244951Sadrian 5244951Sadrian#include <linux/cgroup.h> 6244951Sadrian#include <linux/kernfs.h> 7244951Sadrian#include <linux/workqueue.h> 8244951Sadrian#include <linux/list.h> 9244951Sadrian#include <linux/refcount.h> 10244951Sadrian#include <linux/fs_parser.h> 11244951Sadrian 12244951Sadrian#define TRACE_CGROUP_PATH_LEN 1024 13244951Sadrianextern spinlock_t trace_cgroup_path_lock; 14244951Sadrianextern char trace_cgroup_path[TRACE_CGROUP_PATH_LEN]; 15244951Sadrianextern void __init enable_debug_cgroup(void); 16244951Sadrian 17244951Sadrian/* 18244951Sadrian * cgroup_path() takes a spin lock. It is good practice not to take 19244951Sadrian * spin locks within trace point handlers, as they are mostly hidden 20244951Sadrian * from normal view. As cgroup_path() can take the kernfs_rename_lock 21244951Sadrian * spin lock, it is best to not call that function from the trace event 22244951Sadrian * handler. 23244951Sadrian * 24244951Sadrian * Note: trace_cgroup_##type##_enabled() is a static branch that will only 25244951Sadrian * be set when the trace event is enabled. 26244951Sadrian */ 27244951Sadrian#define TRACE_CGROUP_PATH(type, cgrp, ...) \ 28244951Sadrian do { \ 29244951Sadrian if (trace_cgroup_##type##_enabled()) { \ 30244951Sadrian unsigned long flags; \ 31244951Sadrian spin_lock_irqsave(&trace_cgroup_path_lock, \ 32244951Sadrian flags); \ 33244951Sadrian cgroup_path(cgrp, trace_cgroup_path, \ 34244951Sadrian TRACE_CGROUP_PATH_LEN); \ 35244951Sadrian trace_cgroup_##type(cgrp, trace_cgroup_path, \ 36244951Sadrian ##__VA_ARGS__); \ 37244951Sadrian spin_unlock_irqrestore(&trace_cgroup_path_lock, \ 38244951Sadrian flags); \ 39244951Sadrian } \ 40244951Sadrian } while (0) 41244951Sadrian 42244951Sadrian/* 43244951Sadrian * The cgroup filesystem superblock creation/mount context. 44244951Sadrian */ 45244951Sadrianstruct cgroup_fs_context { 46257176Sglebius struct kernfs_fs_context kfc; 47244951Sadrian struct cgroup_root *root; 48244951Sadrian struct cgroup_namespace *ns; 49244951Sadrian unsigned int flags; /* CGRP_ROOT_* flags */ 50244951Sadrian 51244951Sadrian /* cgroup1 bits */ 52244951Sadrian bool cpuset_clone_children; 53244951Sadrian bool none; /* User explicitly requested empty subsystem */ 54244951Sadrian bool all_ss; /* Seen 'all' option */ 55244951Sadrian u16 subsys_mask; /* Selected subsystems */ 56244951Sadrian char *name; /* Hierarchy name */ 57257176Sglebius char *release_agent; /* Path for release notifications */ 58244951Sadrian}; 59244951Sadrian 60244951Sadrianstatic inline struct cgroup_fs_context *cgroup_fc2context(struct fs_context *fc) 61244951Sadrian{ 62244951Sadrian struct kernfs_fs_context *kfc = fc->fs_private; 63244951Sadrian 64244951Sadrian return container_of(kfc, struct cgroup_fs_context, kfc); 65244951Sadrian} 66244951Sadrian 67244951Sadrianstruct cgroup_pidlist; 68244951Sadrian 69244951Sadrianstruct cgroup_file_ctx { 70244951Sadrian struct cgroup_namespace *ns; 71244951Sadrian 72244951Sadrian struct { 73244951Sadrian void *trigger; 74244951Sadrian } psi; 75244951Sadrian 76244951Sadrian struct { 77244951Sadrian bool started; 78245185Sadrian struct css_task_iter iter; 79245185Sadrian } procs; 80245185Sadrian 81245185Sadrian struct { 82245185Sadrian struct cgroup_pidlist *pidlist; 83245185Sadrian } procs1; 84245185Sadrian}; 85245185Sadrian 86245185Sadrian/* 87245185Sadrian * A cgroup can be associated with multiple css_sets as different tasks may 88245185Sadrian * belong to different cgroups on different hierarchies. In the other 89245185Sadrian * direction, a css_set is naturally associated with multiple cgroups. 90245185Sadrian * This M:N relationship is represented by the following link structure 91245185Sadrian * which exists for each association and allows traversing the associations 92245185Sadrian * from both sides. 93244951Sadrian */ 94244951Sadrianstruct cgrp_cset_link { 95244951Sadrian /* the cgroup and css_set this link associates */ 96244951Sadrian struct cgroup *cgrp; 97244951Sadrian struct css_set *cset; 98244951Sadrian 99244951Sadrian /* list of cgrp_cset_links anchored at cgrp->cset_links */ 100245002Sadrian struct list_head cset_link; 101244951Sadrian 102244951Sadrian /* list of cgrp_cset_links anchored at css_set->cgrp_links */ 103244951Sadrian struct list_head cgrp_link; 104244951Sadrian}; 105244951Sadrian 106244951Sadrian/* used to track tasks and csets during migration */ 107245002Sadrianstruct cgroup_taskset { 108245002Sadrian /* the src and dst cset list running through cset->mg_node */ 109245002Sadrian struct list_head src_csets; 110245002Sadrian struct list_head dst_csets; 111245002Sadrian 112245002Sadrian /* the number of tasks in the set */ 113245002Sadrian int nr_tasks; 114244951Sadrian 115244951Sadrian /* the subsys currently being processed */ 116244951Sadrian int ssid; 117244951Sadrian 118244951Sadrian /* 119244951Sadrian * Fields for cgroup_taskset_*() iteration. 120244951Sadrian * 121244951Sadrian * Before migration is committed, the target migration tasks are on 122244951Sadrian * ->mg_tasks of the csets on ->src_csets. After, on ->mg_tasks of 123244951Sadrian * the csets on ->dst_csets. ->csets point to either ->src_csets 124244951Sadrian * or ->dst_csets depending on whether migration is committed. 125244951Sadrian * 126244951Sadrian * ->cur_csets and ->cur_task point to the current task position 127244951Sadrian * during iteration. 128244951Sadrian */ 129244951Sadrian struct list_head *csets; 130244951Sadrian struct css_set *cur_cset; 131245002Sadrian struct task_struct *cur_task; 132244951Sadrian}; 133244951Sadrian 134244951Sadrian/* migration context also tracks preloading */ 135244951Sadrianstruct cgroup_mgctx { 136245002Sadrian /* 137245002Sadrian * Preloaded source and destination csets. Used to guarantee 138245002Sadrian * atomic success or failure on actual migration. 139245002Sadrian */ 140244951Sadrian struct list_head preloaded_src_csets; 141244951Sadrian struct list_head preloaded_dst_csets; 142244951Sadrian 143244951Sadrian /* tasks and csets to migrate */ 144244951Sadrian struct cgroup_taskset tset; 145244951Sadrian 146244951Sadrian /* subsystems affected by migration */ 147244951Sadrian u16 ss_mask; 148244951Sadrian}; 149244951Sadrian 150244951Sadrian#define CGROUP_TASKSET_INIT(tset) \ 151244951Sadrian{ \ 152244951Sadrian .src_csets = LIST_HEAD_INIT(tset.src_csets), \ 153245185Sadrian .dst_csets = LIST_HEAD_INIT(tset.dst_csets), \ 154244951Sadrian .csets = &tset.src_csets, \ 155245185Sadrian} 156245185Sadrian 157245185Sadrian#define CGROUP_MGCTX_INIT(name) \ 158245185Sadrian{ \ 159245185Sadrian LIST_HEAD_INIT(name.preloaded_src_csets), \ 160245185Sadrian LIST_HEAD_INIT(name.preloaded_dst_csets), \ 161245185Sadrian CGROUP_TASKSET_INIT(name.tset), \ 162245185Sadrian} 163245185Sadrian 164245185Sadrian#define DEFINE_CGROUP_MGCTX(name) \ 165245185Sadrian struct cgroup_mgctx name = CGROUP_MGCTX_INIT(name) 166245185Sadrian 167244951Sadrianextern struct cgroup_subsys *cgroup_subsys[]; 168244951Sadrianextern struct list_head cgroup_roots; 169244951Sadrian 170244951Sadrian/* iterate across the hierarchies */ 171244951Sadrian#define for_each_root(root) \ 172244951Sadrian list_for_each_entry_rcu((root), &cgroup_roots, root_list, \ 173244951Sadrian lockdep_is_held(&cgroup_mutex)) 174244951Sadrian 175244951Sadrian/** 176244951Sadrian * for_each_subsys - iterate all enabled cgroup subsystems 177244951Sadrian * @ss: the iteration cursor 178244951Sadrian * @ssid: the index of @ss, CGROUP_SUBSYS_COUNT after reaching the end 179244951Sadrian */ 180244951Sadrian#define for_each_subsys(ss, ssid) \ 181244951Sadrian for ((ssid) = 0; (ssid) < CGROUP_SUBSYS_COUNT && \ 182244951Sadrian (((ss) = cgroup_subsys[ssid]) || true); (ssid)++) 183244951Sadrian 184244951Sadrianstatic inline bool cgroup_is_dead(const struct cgroup *cgrp) 185244951Sadrian{ 186244951Sadrian return !(cgrp->self.flags & CSS_ONLINE); 187244951Sadrian} 188244951Sadrian 189245185Sadrianstatic inline bool notify_on_release(const struct cgroup *cgrp) 190244951Sadrian{ 191245002Sadrian return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); 192245002Sadrian} 193245002Sadrian 194244951Sadrianvoid put_css_set_locked(struct css_set *cset); 195244951Sadrian 196244951Sadrianstatic inline void put_css_set(struct css_set *cset) 197244951Sadrian{ 198244951Sadrian unsigned long flags; 199244951Sadrian 200244951Sadrian /* 201244951Sadrian * Ensure that the refcount doesn't hit zero while any readers 202244951Sadrian * can see it. Similar to atomic_dec_and_lock(), but for an 203244951Sadrian * rwlock 204244951Sadrian */ 205244951Sadrian if (refcount_dec_not_one(&cset->refcount)) 206244951Sadrian return; 207244951Sadrian 208244951Sadrian spin_lock_irqsave(&css_set_lock, flags); 209244951Sadrian put_css_set_locked(cset); 210244951Sadrian spin_unlock_irqrestore(&css_set_lock, flags); 211244951Sadrian} 212244951Sadrian 213244951Sadrian/* 214244951Sadrian * refcounted get/put for css_set objects 215244951Sadrian */ 216244951Sadrianstatic inline void get_css_set(struct css_set *cset) 217244951Sadrian{ 218244951Sadrian refcount_inc(&cset->refcount); 219244951Sadrian} 220244951Sadrian 221244951Sadrianbool cgroup_ssid_enabled(int ssid); 222244951Sadrianbool cgroup_on_dfl(const struct cgroup *cgrp); 223244951Sadrian 224244951Sadrianstruct cgroup_root *cgroup_root_from_kf(struct kernfs_root *kf_root); 225244951Sadrianstruct cgroup *task_cgroup_from_root(struct task_struct *task, 226244951Sadrian struct cgroup_root *root); 227244951Sadrianstruct cgroup *cgroup_kn_lock_live(struct kernfs_node *kn, bool drain_offline); 228244951Sadrianvoid cgroup_kn_unlock(struct kernfs_node *kn); 229244951Sadrianint cgroup_path_ns_locked(struct cgroup *cgrp, char *buf, size_t buflen, 230244951Sadrian struct cgroup_namespace *ns); 231244951Sadrian 232244951Sadrianvoid cgroup_favor_dynmods(struct cgroup_root *root, bool favor); 233244951Sadrianvoid cgroup_free_root(struct cgroup_root *root); 234244951Sadrianvoid init_cgroup_root(struct cgroup_fs_context *ctx); 235244951Sadrianint cgroup_setup_root(struct cgroup_root *root, u16 ss_mask); 236244951Sadrianint rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask); 237244951Sadrianint cgroup_do_get_tree(struct fs_context *fc); 238244951Sadrian 239244951Sadrianint cgroup_migrate_vet_dst(struct cgroup *dst_cgrp); 240244951Sadrianvoid cgroup_migrate_finish(struct cgroup_mgctx *mgctx); 241244951Sadrianvoid cgroup_migrate_add_src(struct css_set *src_cset, struct cgroup *dst_cgrp, 242244951Sadrian struct cgroup_mgctx *mgctx); 243244951Sadrianint cgroup_migrate_prepare_dst(struct cgroup_mgctx *mgctx); 244245185Sadrianint cgroup_migrate(struct task_struct *leader, bool threadgroup, 245245185Sadrian struct cgroup_mgctx *mgctx); 246244951Sadrian 247244951Sadrianint cgroup_attach_task(struct cgroup *dst_cgrp, struct task_struct *leader, 248244951Sadrian bool threadgroup); 249245185Sadrianvoid cgroup_attach_lock(bool lock_threadgroup); 250245185Sadrianvoid cgroup_attach_unlock(bool lock_threadgroup); 251244951Sadrianstruct task_struct *cgroup_procs_write_start(char *buf, bool threadgroup, 252245185Sadrian bool *locked) 253245185Sadrian __acquires(&cgroup_threadgroup_rwsem); 254245185Sadrianvoid cgroup_procs_write_finish(struct task_struct *task, bool locked) 255245185Sadrian __releases(&cgroup_threadgroup_rwsem); 256245190Sadrian 257245185Sadrianvoid cgroup_lock_and_drain_offline(struct cgroup *cgrp); 258245185Sadrian 259245185Sadrianint cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode); 260245185Sadrianint cgroup_rmdir(struct kernfs_node *kn); 261245185Sadrianint cgroup_show_path(struct seq_file *sf, struct kernfs_node *kf_node, 262245185Sadrian struct kernfs_root *kf_root); 263245185Sadrian 264245185Sadrianint __cgroup_task_count(const struct cgroup *cgrp); 265245185Sadrianint cgroup_task_count(const struct cgroup *cgrp); 266245185Sadrian 267245185Sadrian/* 268245185Sadrian * rstat.c 269245185Sadrian */ 270245185Sadrianint cgroup_rstat_init(struct cgroup *cgrp); 271244951Sadrianvoid cgroup_rstat_exit(struct cgroup *cgrp); 272244951Sadrianvoid cgroup_rstat_boot(void); 273244951Sadrianvoid cgroup_base_stat_cputime_show(struct seq_file *seq); 274244951Sadrian 275244951Sadrian/* 276244951Sadrian * namespace.c 277244951Sadrian */ 278244951Sadrianextern const struct proc_ns_operations cgroupns_operations; 279244951Sadrian 280244951Sadrian/* 281244951Sadrian * cgroup-v1.c 282244951Sadrian */ 283244951Sadrianextern struct cftype cgroup1_base_files[]; 284244951Sadrianextern struct kernfs_syscall_ops cgroup1_kf_syscall_ops; 285244951Sadrianextern const struct fs_parameter_spec cgroup1_fs_parameters[]; 286244951Sadrian 287244951Sadrianint proc_cgroupstats_show(struct seq_file *m, void *v); 288244951Sadrianbool cgroup1_ssid_disabled(int ssid); 289244951Sadrianvoid cgroup1_pidlist_destroy_all(struct cgroup *cgrp); 290244951Sadrianvoid cgroup1_release_agent(struct work_struct *work); 291void cgroup1_check_for_release(struct cgroup *cgrp); 292int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param); 293int cgroup1_get_tree(struct fs_context *fc); 294int cgroup1_reconfigure(struct fs_context *ctx); 295 296#endif /* __CGROUP_INTERNAL_H */ 297