structtask_struct { ... #ifdef CONFIG_CGROUPS /* Control Group info protected by css_set_lock */ structcss_set __rcu *cgroups; /* cg_list protected by css_set_lock and tsk->alloc_lock */ structlist_headcg_list; #endif ... };
/* * A css_set is a structure holding pointers to a set of * cgroup_subsys_state objects. This saves space in the task struct * object and speeds up fork()/exit(), since a single inc/dec and a * list_add()/del() can bump the reference count on the entire cgroup * set for a task. */
/* * List running through all cgroup groups in the same hash * slot. Protected by css_set_lock */ structhlist_nodehlist;
/* * List running through all tasks using this cgroup * group. Protected by css_set_lock */ structlist_headtasks;
/* * List of cg_cgroup_link objects on link chains from * cgroups referenced from this css_set. Protected by * css_set_lock */ //由cg_cgroup_link组成的链表,链表上每一项cg_cgroup_link都指向和css_set关联的cgroup. structlist_headcg_links;
/* * Set of subsystem states, one for each subsystem. This array * is immutable after creation apart from the init_css_set * during subsystem registration (at boot time) and modular subsystem * loading/unloading. */ /* *css_set关联的css.每一个subsystem对应数组中相应id的项。 *subsys应当包括所有子系统的css.如果此css_set没有制定某个subsystem的css或者subsystem没有mount,则默认初始化为根css. */ structcgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];//是进程与一个特定子系统相关的信息
/* For RCU-protected deletion */ structrcu_headrcu_head; };
/* Per-subsystem/per-cgroup state maintained by the system. */ structcgroup_subsys_state { /* * The cgroup that this subsystem is attached to. Useful * for subsystems that want to know about the cgroup * hierarchy structure */ structcgroup *cgroup;
/* * State maintained by the cgroup system to allow subsystems * to be "busy". Should be accessed via css_get(), * css_tryget() and css_put(). */
atomic_t refcnt;
unsignedlong flags; /* ID for this css, if possible */ structcss_id __rcu *id;
/* Used to put @cgroup->dentry on the last css_put() */ structwork_structdput_work; };
structcgroup { unsignedlong flags; /* "unsigned long" so bitops work */
/* * count users of this cgroup. >0 means busy, but doesn't * necessarily indicate the number of tasks in the cgroup */ atomic_t count;
int id; /* ida allocated in-hierarchy ID */
/* * We link our 'sibling' struct into our parent's 'children'. * Our children link their 'sibling' into our 'children'. */ structlist_headsibling;/* my parent's children */ structlist_headchildren;/* my children */ structlist_headfiles;/* my files */
/* * This is a copy of dentry->d_name, and it's needed because * we can't use dentry->d_name in cgroup_path(). * * You must acquire rcu_read_lock() to access cgrp->name, and * the only place that can change it is rename(), which is * protected by parent dir's i_mutex. * * Normally you should use cgroup_name() wrapper rather than * access it directly. */ structcgroup_name __rcu *name;
/* Private pointers for each registered subsystem */ //此cgroup关联subsystem的css结构,每个subsystem的css在数组中对应subsys[subsystem->subsys_id]. structcgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
structcgroupfs_root *root;
/* * List of cg_cgroup_links pointing at css_sets with * tasks in this cgroup. Protected by css_set_lock */ structlist_headcss_sets;//通过cs_cgroup_link指向此cgroup关联的css_set
structlist_headallcg_node;/* cgroupfs_root->allcg_list */ structlist_headcft_q_node;/* used during cftype add/rm */
/* * Linked list running through all cgroups that can * potentially be reaped by the release agent. Protected by * release_list_lock */ structlist_headrelease_list;
/* * list of pidlists, up to two for each namespace (one for procs, one * for tasks); created on demand. */ structlist_headpidlists; structmutexpidlist_mutex;
/* For RCU-protected deletion */ structrcu_headrcu_head; structwork_structfree_work;
/* List of events which userspace want to receive */ structlist_headevent_list; spinlock_t event_list_lock;
/* Link structure for associating css_set objects with cgroups */ structcg_cgroup_link { /* * List running through cg_cgroup_links associated with a * cgroup, anchored on cgroup->css_sets */ structlist_headcgrp_link_list; structcgroup *cgrp; /* * List running through cg_cgroup_links pointing at a * single css_set object, anchored on css_set->cg_links */ structlist_headcg_link_list; structcss_set *cg; };
/* * A cgroupfs_root represents the root of a cgroup hierarchy, and may be * associated with a superblock to form an active hierarchy. This is * internal to cgroup core. Don't access directly from controllers. */ structcgroupfs_root { structsuper_block *sb;//cgroup文件系统的超级块
/* * The bitmask of subsystems intended to be attached to this * hierarchy */ unsignedlong subsys_mask; //hierarchy相关联的subsys 位图
/* Unique id for this hierarchy. */ int hierarchy_id;
/* The bitmask of subsystems currently attached to this hierarchy */ unsignedlong actual_subsys_mask;
/* A list running through the attached subsystems */ structlist_headsubsys_list;//hierarchy中的subsys链表
/* The root cgroup for this hierarchy */ structcgrouptop_cgroup;
/* Tracks how many cgroups are currently defined in hierarchy.*/ int number_of_cgroups;
/* A list running through the active hierarchies */ structlist_headroot_list;
/* All cgroups on this root, cgroup_mutex protected */ structlist_headallcg_list;
int subsys_id; int disabled; int early_init; /* * True if this subsys uses ID. ID is not available before cgroup_init() * (not available in early_init time.) */ bool use_id;
/* * If %false, this subsystem is properly hierarchical - * configuration, resource accounting and restriction on a parent * cgroup cover those of its children. If %true, hierarchy support * is broken in some ways - some subsystems ignore hierarchy * completely while others are only implemented half-way. * * It's now disallowed to create nested cgroups if the subsystem is * broken and cgroup core will emit a warning message on such * cases. Eventually, all subsystems will be made properly * hierarchical and this will go away. */
/* * Link to parent, and list entry in parent's children. * Protected by cgroup_lock() */ structcgroupfs_root *root; structlist_headsibling; /* used when use_id == true */ structidridr; spinlock_t id_lock;
/* list of cftype_sets */ structlist_headcftsets;
/* base cftypes, automatically [de]registered with subsys itself */ structcftype *base_cftypes; structcftype_setbase_cftset;
/* should be defined only by modular subsystems */ structmodule *module; };
/** * cgroup_init - cgroup initialization * * Register cgroup filesystem and /proc file, and initialize * any subsystems that didn't request early init. */
int __init cgroup_init(void) { ... err = bdi_init(&cgroup_backing_dev_info);
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { structcgroup_subsys *ss = subsys[i];
/* at bootup time, we don't worry about modular subsystems */ if (!ss || ss->module) continue; if (!ss->early_init) cgroup_init_subsys(ss); if (ss->use_id) cgroup_init_idr(ss, init_css_set.subsys[ss->subsys_id]); }
/* Add init_css_set to the hash table */ key = css_set_hash(init_css_set.subsys); hash_add(css_set_table, &init_css_set.hlist, key); BUG_ON(!init_root_id(&rootnode)); ... cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj);