cgroup: prepare for the default unified hierarchy
Subsystems (9)
Tejun Heo
maintainerPATCH 1/1 cgroup: prepare for the default unified hierarchy
Hello,
The planned unified hierarchy is just around the corner. We're gonna repurpose the dummy hierarchy to serve as the default unified hierarchy. Controllers which aren't attached to other hierarchies are already automatically bound to the dummy hierarchy; however, the dummy hierarchy is minimally initialized during boot and can't currently act as a full hierarchy.
This patchset gradually turns the dummy hierarchy into fully functional default one and makes it mountable via selecting sane_behavior without any subsystems specified. While this patchset does make the default hierarchy mountable, the unified hierarchy functionality isn't implemented yet and cgroup creation in the default hierarchy is rejected for now.
This lays down all the boilerplate work for the unified hierarchy. The next patchset will implement the actual unified functionality.
This patchset contains the following eleven patches.
0001-cgroup-cgroup-subsys-should-be-cleared-after-the-css.patch 0002-cgroup-relocate-setting-of-CGRP_DEAD.patch 0003-cgroup-reorganize-cgroup-bootstrapping.patch 0004-cgroup-use-cgroup_setup_root-to-initialize-cgroup_du.patch 0005-cgroup-remove-NULL-checks-from-pr_cont_-cgroup_-name.patch 0006-cgroup-treat-cgroup_dummy_root-as-an-equivalent-hier.patch 0007-cgroup-move-subsys_mask-from-cgroupfs_root-to-cgroup.patch 0008-cgroup-rename-cgroup_dummy_root-and-related-names.patch 0009-cgroup-drop-const-from-buffer-of-cftype-write_string.patch 0010-cgroup-make-cgrp_dfl_root-mountable.patch 0011-cgroup-implement-CFTYPE_ONLY_ON_DFL.patch
0001-0002 are misc fix / prep.
0003-0009 (mostly) turn the dummy hierarchy into a full hierarchy which takes on controllers which aren't attached to other hierarchies.
0010-0011 make the default hierarchy mountable and implement CFTYPE_ONLY_DFL.
This patchset is on top of cgroup/for-3.15 b8dadcb58d54 ("cpuset: use rcu_read_lock() to protect task_cs()"). diffstat follows.
block/blk-throttle.c | 4 block/cfq-iosched.c | 4 include/linux/cgroup.h | 57 ++--- kernel/cgroup.c | 464 +++++++++++++++++++++++++--------------------- kernel/cgroup_freezer.c | 2 kernel/cpuset.c | 2 mm/hugetlb_cgroup.c | 2 mm/memcontrol.c | 4 net/core/netprio_cgroup.c | 2 net/ipv4/tcp_memcontrol.c | 2 security/device_cgroup.c | 4 11 files changed, 295 insertions(+), 252 deletions(-)
Thanks.
--
tejun
Tejun Heo
maintainerPATCH 1/11 cgroup: cgroup->subsys[] should be cleared after the css is offlined
After a css finishes offlining, offline_css() mistakenly performs RCU_INIT_POINTER(css->cgroup->subsys[ss->id], css) which just sets the cgroup->subsys[] pointer to the current value. The intention was to clear it after offline is complete, not reassign the same value.
Update it to assign NULL instead of the current value. This makes cgroup_css() to return NULL once offline is complete. All the existing users of the function either can handle NULL return already or guarantee that the css doesn't get offlined.
While this is a bugfix, as css lifetime is currently tied to the cgroup it belongs to, this bug doesn't cause any actual problems.
--- kernel/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/cgroup.c +1 -1
@@ -3535,7 +3535,7 @@ static void offline_css(struct cgroup_subsys_state *css) css->flags &= ~CSS_ONLINE ; css->cgroup->nr_css--; -RCU_INIT_POINTER (css->cgroup->subsys[ss->id], css); +RCU_INIT_POINTER (css->cgroup->subsys[ss->id],NULL ); }/**
Signature · 1 line
1.8.5.3
Tejun Heo
maintainerPATCH 2/11 cgroup: relocate setting of CGRP_DEAD
In reply to Tejun HeoIn cgroup_destroy_locked(), move setting of CGRP_DEAD above invocations of kill_css(). This doesn't make any visible behavior difference now but will be used to inhibit manipulating controller enable states of a dying cgroup on the unified hierarchy.
--- kernel/cgroup.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
kernel/cgroup.c +9 -9
@@ -3868,6 +3868,15 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)return -EBUSY ;/* +* Mark @cgrp dead. This prevents further task migration and child +* creation by disabling cgroup_lock_live_group(). Note that +* CGRP_DEAD assertion is depended upon by css_next_child() to +* resume iteration after dropping RCU read lock. See +* css_next_child() for details. +*/ +set_bit (CGRP_DEAD , &cgrp->flags); + +/* * Initiate massacre of all css's. cgroup_destroy_css_killed() * will be invoked to perform the rest of destruction once the * percpu refs of all css's are confirmed to be killed. This
@@ -3878,15 +3887,6 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)kill_css (css);mutex_lock (&cgroup_mutex); -/* -* Mark @cgrp dead. This prevents further task migration and child -* creation by disabling cgroup_lock_live_group(). Note that -* CGRP_DEAD assertion is depended upon by css_next_child() to -* resume iteration after dropping RCU read lock. See -* css_next_child() for details. -*/ -set_bit (CGRP_DEAD , &cgrp->flags); -/* CGRP_DEAD is set, remove from ->release_list for the last time */ raw_spin_lock (&release_list_lock);if (!list_empty (&cgrp->release_list))
Signature · 1 line
1.8.5.3
Tejun Heo
maintainerPATCH 3/11 cgroup: reorganize cgroup bootstrapping
In reply to Tejun Heo* Fields of init_css_set and css_set_count are now set using initializer instead of programmatically from cgroup_init_early().
* init_cgroup_root() now also takes @opts and performs the optional part of initialization too. The leftover part of cgroup_root_from_opts() is collapsed into its only caller - cgroup_mount().
* Initialization of cgroup_root_count and linking of init_css_set are moved from cgroup_init_early() to to cgroup_init(). None of the early_init users depends on init_css_set being linked.
* Subsystem initializations are moved after dummy hierarchy init and init_css_set linking.
These changes reorganize the bootstrap logic so that the dummy hierarchy can share the usual hierarchy init path and be made more normal. These changes don't make noticeable behavior changes.
--- kernel/cgroup.c | 100 +++++++++++++++++++++++++++----------------------------- 1 file changed, 49 insertions(+), 51 deletions(-)
kernel/cgroup.c +49 -51
@@ -338,16 +338,24 @@ struct cgrp_cset_link {struct list_head cgrp_link; }; -/* The default css_set - used by init and its children prior to any +/* +* The default css_set - used by init and its children prior to any * hierarchies being mounted. It contains a pointer to the root state * for each subsystem. Also used to anchor the list of css_sets. Not * reference-counted, to improve performance when child cgroups * haven't been created. */ +static struct css_set init_css_set = { + .refcount =ATOMIC_INIT (1 ), + .cgrp_links =LIST_HEAD_INIT (init_css_set.cgrp_links), + .tasks =LIST_HEAD_INIT (init_css_set.tasks), + .mg_tasks =LIST_HEAD_INIT (init_css_set.mg_tasks), + .mg_preload_node =LIST_HEAD_INIT (init_css_set.mg_preload_node), + .mg_node =LIST_HEAD_INIT (init_css_set.mg_node), +}; -static struct css_set init_css_set;static struct cgrp_cset_link init_cgrp_cset_link; -static int css_set_count; +static int css_set_count =1 ;/* 1 for init_css_set */ /* * hash table for cgroup groups. This improves the performance to find
@@ -1352,7 +1360,8 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp) cgrp->dummy_css.cgroup = cgrp; } -static void init_cgroup_root (struct cgroupfs_root *root) +static void init_cgroup_root (struct cgroupfs_root *root, +struct cgroup_sb_opts *opts) {struct cgroup *cgrp = &root->top_cgroup;
@@ -1361,20 +1370,6 @@ static void init_cgroup_root(struct cgroupfs_root *root) cgrp->root = root;init_cgroup_housekeeping (cgrp);idr_init (&root->cgroup_idr); -} - -static struct cgroupfs_root *cgroup_root_from_opts (struct cgroup_sb_opts *opts) -{ -struct cgroupfs_root *root; - -if (!opts->subsys_mask && !opts->none) -return ERR_PTR (-EINVAL ); - - root =kzalloc (sizeof (*root),GFP_KERNEL ); -if (!root) -return ERR_PTR (-ENOMEM ); - -init_cgroup_root (root); root->flags = opts->flags;if (opts->release_agent)
@@ -1383,7 +1378,6 @@ static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts)strcpy (root->name, opts->name);if (opts->cpuset_clone_children)set_bit (CGRP_CPUSET_CLONE_CHILDREN , &root->top_cgroup.flags); -return root; }static int cgroup_setup_root (struct cgroupfs_root *root,unsigned long ss_mask)
@@ -1548,13 +1542,24 @@ retry: goto out_unlock; } -/* no such thing, create a new one */ - root =cgroup_root_from_opts (&opts); -if (IS_ERR (root)) { - ret =PTR_ERR (root); +/* +* No such thing, create a new one. name= matching without subsys +* specification is allowed for already existing hierarchies but we +* can't create new one without subsys specification. +*/ +if (!opts.subsys_mask && !opts.none) { + ret = -EINVAL ; + goto out_unlock; + } + + root =kzalloc (sizeof (*root),GFP_KERNEL ); +if (!root) { + ret = -ENOMEM ; goto out_unlock; } +init_cgroup_root (root, &opts); + ret =cgroup_setup_root (root, opts.subsys_mask);if (ret)cgroup_free_root (root);
@@ -4030,26 +4035,13 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)*/ int __init cgroup_init_early (void ) { +static struct cgroup_sb_opts __initdata opts = { };struct cgroup_subsys *ss;int i; -atomic_set (&init_css_set.refcount,1 ); -INIT_LIST_HEAD (&init_css_set.cgrp_links); -INIT_LIST_HEAD (&init_css_set.tasks); -INIT_LIST_HEAD (&init_css_set.mg_tasks); -INIT_LIST_HEAD (&init_css_set.mg_preload_node); -INIT_LIST_HEAD (&init_css_set.mg_node); -INIT_HLIST_NODE (&init_css_set.hlist); - css_set_count =1 ; -init_cgroup_root (&cgroup_dummy_root); - cgroup_root_count =1 ; +init_cgroup_root (&cgroup_dummy_root, &opts);RCU_INIT_POINTER (init_task.cgroups, &init_css_set); - init_cgrp_cset_link.cset = &init_css_set; - init_cgrp_cset_link.cgrp = cgroup_dummy_top; -list_add (&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links); -list_add (&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links); -for_each_subsys (ss, i) { WARN(!ss->css_alloc || !ss->css_free || ss->name || ss->id, "invalid cgroup_subsys %d:%s css_alloc=%p css_free=%p name:id=%d:%s\n",
@@ -4077,22 +4069,10 @@ int __init cgroup_init(void) {struct cgroup_subsys *ss;unsigned long key; -int i, err; +int ssid, err;BUG_ON (cgroup_init_cftypes (NULL , cgroup_base_files)); -for_each_subsys (ss, i) { -if (!ss->early_init) -cgroup_init_subsys (ss); - -/* -* cftype registration needs kmalloc and can't be done -* during early_init. Register base cftypes separately. -*/ -if (ss->base_cftypes) -WARN_ON (cgroup_add_cftypes (ss, ss->base_cftypes)); - } -/* allocate id for the dummy hierarchy */ mutex_lock (&cgroup_mutex);
@@ -4106,8 +4086,26 @@ int __init cgroup_init(void) 0, 1, GFP_KERNEL);BUG_ON (err <0 ); + cgroup_root_count =1 ; + init_cgrp_cset_link.cset = &init_css_set; + init_cgrp_cset_link.cgrp = cgroup_dummy_top; +list_add (&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links); +list_add (&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links); +mutex_unlock (&cgroup_mutex); +for_each_subsys (ss, ssid) { +if (!ss->early_init) +cgroup_init_subsys (ss); + +/* +* cftype registration needs kmalloc and can't be done +* during early_init. Register base cftypes separately. +*/ +if (ss->base_cftypes) +WARN_ON (cgroup_add_cftypes (ss, ss->base_cftypes)); + } + cgroup_kobj =kobject_create_and_add ("cgroup" , fs_kobj);if (!cgroup_kobj)return -ENOMEM ;
Signature · 1 line
1.8.5.3
A message that is not in the archive (sent off-list or not yet received): 1394740213-17626-1-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
PATCH 3/11 cgroup: reorganize cgroup bootstrapping
* Fields of init_css_set and css_set_count are now set using initializer instead of programmatically from cgroup_init_early().
* init_cgroup_root() now also takes @opts and performs the optional part of initialization too. The leftover part of cgroup_root_from_opts() is collapsed into its only caller - cgroup_mount().
* Initialization of cgroup_root_count and linking of init_css_set are moved from cgroup_init_early() to to cgroup_init(). None of the early_init users depends on init_css_set being linked.
* Subsystem initializations are moved after dummy hierarchy init and init_css_set linking.
These changes reorganize the bootstrap logic so that the dummy hierarchy can share the usual hierarchy init path and be made more normal. These changes don't make noticeable behavior changes.
--- kernel/cgroup.c | 100 +++++++++++++++++++++++++++----------------------------- 1 file changed, 49 insertions(+), 51 deletions(-)
kernel/cgroup.c +49 -51
@@ -338,16 +338,24 @@ struct cgrp_cset_link {struct list_head cgrp_link; }; -/* The default css_set - used by init and its children prior to any +/* +* The default css_set - used by init and its children prior to any * hierarchies being mounted. It contains a pointer to the root state * for each subsystem. Also used to anchor the list of css_sets. Not * reference-counted, to improve performance when child cgroups * haven't been created. */ +static struct css_set init_css_set = { + .refcount =ATOMIC_INIT (1 ), + .cgrp_links =LIST_HEAD_INIT (init_css_set.cgrp_links), + .tasks =LIST_HEAD_INIT (init_css_set.tasks), + .mg_tasks =LIST_HEAD_INIT (init_css_set.mg_tasks), + .mg_preload_node =LIST_HEAD_INIT (init_css_set.mg_preload_node), + .mg_node =LIST_HEAD_INIT (init_css_set.mg_node), +}; -static struct css_set init_css_set;static struct cgrp_cset_link init_cgrp_cset_link; -static int css_set_count; +static int css_set_count =1 ;/* 1 for init_css_set */ /* * hash table for cgroup groups. This improves the performance to find
@@ -1352,7 +1360,8 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp) cgrp->dummy_css.cgroup = cgrp; } -static void init_cgroup_root (struct cgroupfs_root *root) +static void init_cgroup_root (struct cgroupfs_root *root, +struct cgroup_sb_opts *opts) {struct cgroup *cgrp = &root->top_cgroup;
@@ -1361,20 +1370,6 @@ static void init_cgroup_root(struct cgroupfs_root *root) cgrp->root = root;init_cgroup_housekeeping (cgrp);idr_init (&root->cgroup_idr); -} - -static struct cgroupfs_root *cgroup_root_from_opts (struct cgroup_sb_opts *opts) -{ -struct cgroupfs_root *root; - -if (!opts->subsys_mask && !opts->none) -return ERR_PTR (-EINVAL ); - - root =kzalloc (sizeof (*root),GFP_KERNEL ); -if (!root) -return ERR_PTR (-ENOMEM ); - -init_cgroup_root (root); root->flags = opts->flags;if (opts->release_agent)
@@ -1383,7 +1378,6 @@ static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts)strcpy (root->name, opts->name);if (opts->cpuset_clone_children)set_bit (CGRP_CPUSET_CLONE_CHILDREN , &root->top_cgroup.flags); -return root; }static int cgroup_setup_root (struct cgroupfs_root *root,unsigned long ss_mask)
@@ -1548,13 +1542,24 @@ retry: goto out_unlock; } -/* no such thing, create a new one */ - root =cgroup_root_from_opts (&opts); -if (IS_ERR (root)) { - ret =PTR_ERR (root); +/* +* No such thing, create a new one. name= matching without subsys +* specification is allowed for already existing hierarchies but we +* can't create new one without subsys specification. +*/ +if (!opts.subsys_mask && !opts.none) { + ret = -EINVAL ; + goto out_unlock; + } + + root =kzalloc (sizeof (*root),GFP_KERNEL ); +if (!root) { + ret = -ENOMEM ; goto out_unlock; } +init_cgroup_root (root, &opts); + ret =cgroup_setup_root (root, opts.subsys_mask);if (ret)cgroup_free_root (root);
@@ -4030,26 +4035,13 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)*/ int __init cgroup_init_early (void ) { +static struct cgroup_sb_opts __initdata opts = { };struct cgroup_subsys *ss;int i; -atomic_set (&init_css_set.refcount,1 ); -INIT_LIST_HEAD (&init_css_set.cgrp_links); -INIT_LIST_HEAD (&init_css_set.tasks); -INIT_LIST_HEAD (&init_css_set.mg_tasks); -INIT_LIST_HEAD (&init_css_set.mg_preload_node); -INIT_LIST_HEAD (&init_css_set.mg_node); -INIT_HLIST_NODE (&init_css_set.hlist); - css_set_count =1 ; -init_cgroup_root (&cgroup_dummy_root); - cgroup_root_count =1 ; +init_cgroup_root (&cgroup_dummy_root, &opts);RCU_INIT_POINTER (init_task.cgroups, &init_css_set); - init_cgrp_cset_link.cset = &init_css_set; - init_cgrp_cset_link.cgrp = cgroup_dummy_top; -list_add (&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links); -list_add (&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links); -for_each_subsys (ss, i) { WARN(!ss->css_alloc || !ss->css_free || ss->name || ss->id, "invalid cgroup_subsys %d:%s css_alloc=%p css_free=%p name:id=%d:%s\n",
@@ -4077,22 +4069,10 @@ int __init cgroup_init(void) {struct cgroup_subsys *ss;unsigned long key; -int i, err; +int ssid, err;BUG_ON (cgroup_init_cftypes (NULL , cgroup_base_files)); -for_each_subsys (ss, i) { -if (!ss->early_init) -cgroup_init_subsys (ss); - -/* -* cftype registration needs kmalloc and can't be done -* during early_init. Register base cftypes separately. -*/ -if (ss->base_cftypes) -WARN_ON (cgroup_add_cftypes (ss, ss->base_cftypes)); - } -/* allocate id for the dummy hierarchy */ mutex_lock (&cgroup_mutex);
@@ -4106,8 +4086,26 @@ int __init cgroup_init(void) 0, 1, GFP_KERNEL);BUG_ON (err <0 ); + cgroup_root_count =1 ; + init_cgrp_cset_link.cset = &init_css_set; + init_cgrp_cset_link.cgrp = cgroup_dummy_top; +list_add (&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links); +list_add (&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links); +mutex_unlock (&cgroup_mutex); +for_each_subsys (ss, ssid) { +if (!ss->early_init) +cgroup_init_subsys (ss); + +/* +* cftype registration needs kmalloc and can't be done +* during early_init. Register base cftypes separately. +*/ +if (ss->base_cftypes) +WARN_ON (cgroup_add_cftypes (ss, ss->base_cftypes)); + } + cgroup_kobj =kobject_create_and_add ("cgroup" , fs_kobj);if (!cgroup_kobj)return -ENOMEM ;
Signature · 1 line
1.8.5.3
PATCH 5/11 cgroup: remove NULL checks from [pr_cont_]cgroup_{name|path}()
In reply to a message not in the archiveThe dummy hierarchy is now a fully functional one and dummy_top has a kernfs_node associated with it. Drop the NULL checks in [pr_cont_]cont_{name|path}() which are no longer necessary.
--- include/linux/cgroup.h | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-)
include/linux/cgroup.h +4 -20
@@ -508,39 +508,23 @@ struct cgroup_subsys_state *seq_css(struct seq_file *seq);static inline int cgroup_name (struct cgroup *cgrp,char *buf,size_t buflen) { -/* dummy_top doesn't have a kn associated */ -if (cgrp->kn) -return kernfs_name (cgrp->kn, buf, buflen); -else -return strlcpy (buf,"/" , buflen); +return kernfs_name (cgrp->kn, buf, buflen); }static inline char *__must_check cgroup_path (struct cgroup *cgrp,char *buf,size_t buflen) { -/* dummy_top doesn't have a kn associated */ -if (cgrp->kn) -return kernfs_path (cgrp->kn, buf, buflen); -strlcpy (buf,"/" , buflen); -return (buflen <=2 ) ?NULL : buf; +return kernfs_path (cgrp->kn, buf, buflen); }static inline void pr_cont_cgroup_name (struct cgroup *cgrp) { -/* dummy_top doesn't have a kn associated */ -if (cgrp->kn) -pr_cont_kernfs_name (cgrp->kn); -else -pr_cont ("/" ); +pr_cont_kernfs_name (cgrp->kn); }static inline void pr_cont_cgroup_path (struct cgroup *cgrp) { -/* dummy_top doesn't have a kn associated */ -if (cgrp->kn) -pr_cont_kernfs_path (cgrp->kn); -else -pr_cont ("/" ); +pr_cont_kernfs_path (cgrp->kn); }char *task_cgroup_path (struct task_struct *task,char *buf,size_t buflen);
Signature · 1 line
1.8.5.3
PATCH 8/11 cgroup: rename cgroup_dummy_root and related names
In reply to a message not in the archiveThe dummy root will be repurposed to serve as the default unified hierarchy. Let's rename things in preparation.
* s/cgroup_dummy_root/cgrp_dfl_root/
* s/cgroupfs_root/cgroup_root/ as we don't do fs part directly anymore
* s/cgroup_root->top_cgroup/cgroup_root->cgrp/ for brevity
This is pure rename.
--- include/linux/cgroup.h | 14 ++--- kernel/cgroup.c | 168 ++++++++++++++++++++++++------------------------- 2 files changed, 88 insertions(+), 94 deletions(-)
include/linux/cgroup.h +7 -7
@@ -24,7 +24,7 @@#ifdef CONFIG_CGROUPS -struct cgroupfs_root ; +struct cgroup_root ;struct cgroup_subsys ;struct inode ;struct cgroup ;
@@ -179,7 +179,7 @@ struct cgroup {/* Private pointers for each registered subsystem */ struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT ]; -struct cgroupfs_root *root; +struct cgroup_root *root;/* * List of cgrp_cset_links pointing at css_sets with tasks in this
@@ -211,7 +211,7 @@ struct cgroup {#define MAX_CGROUP_ROOT_NAMELEN 64 -/* cgroupfs_root->flags */ +/* cgroup_root->flags */ enum {/* * Unfortunately, cgroup core and various controllers are riddled
@@ -272,18 +272,18 @@ enum { };/* -* A cgroupfs_root represents the root of a cgroup hierarchy, and may be +* A cgroup_root represents the root of a cgroup hierarchy, and may be * associated with a kernfs_root to form an active hierarchy. This is * internal to cgroup core. Don't access directly from controllers. */ -struct cgroupfs_root { +struct cgroup_root {struct kernfs_root *kf_root;/* Unique id for this hierarchy. */ int hierarchy_id;/* The root cgroup. Root is destroyed on its release. */ -struct cgroup top_cgroup; +struct cgroup cgrp;/* Number of cgroups in the hierarchy, used only for /proc/cgroups */ atomic_t nr_cgrps;
@@ -598,7 +598,7 @@ struct cgroup_subsys {const char *name;/* link to parent, protected by cgroup_lock() */ -struct cgroupfs_root *root; +struct cgroup_root *root;/* * List of cftypes. Each entry is the first entry of an array
kernel/cgroup.c +81 -87
517 lines not on this page · raw message
Signature · 1 line
1.8.5.3
PATCH 10/11 cgroup: make cgrp_dfl_root mountable
In reply to a message not in the archivecgrp_dfl_root will be used as the default unified hierarchy. This patch makes cgrp_dfl_root mountable by making the following changes.
* cgroup_init_early() now initializes cgrp_dfl_root w/ CGRP_ROOT_SANE_BEHAVIOR. The default hierarchy is always sane.
* parse_cgroupfs_options() and cgroup_mount() are updated such that cgrp_dfl_root is mounted if sane_behavior is specified w/o any subsystems.
* rebind_subsystems() now populates the root directory of cgrp_dfl_root. Note that the function still guarantees success of rebinding subsystems to cgrp_dfl_root. If populating fails while rebinding to cgrp_dfl_root, it whines but ignores the error.
* For backward compatibility, the default hierarchy shows up in /proc/$PID/cgroup only after it's explicitly mounted so that userland which doesn't make use of it doesn't see any change.
* "current_css_set_cg_links" file of debug cgroup now treats the default hierarchy the same as other hierarchies. This is visible to userland. Given that it's for debug controller, this should be fine.
* While at it, implement cgroup_on_dfl() which tests whether a give cgroup is on the default hierarchy or not.
The above changes make cgrp_dfl_root mostly equivalent to other controllers but the actual unified hierarchy behaviors are not implemented yet. Let's plug child cgroup creation in cgrp_dfl_root from create_cgroup() for now.
--- include/linux/cgroup.h | 10 ++++++ kernel/cgroup.c | 94 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 71 insertions(+), 33 deletions(-)
include/linux/cgroup.h +10 -0
@@ -250,6 +250,9 @@ enum {* * - "cgroup.clone_children" is removed. * +* - If mount is requested with sane_behavior but without any +* subsystem, the default unified hierarchy is mounted. +* * - cpuset: tasks will be kept in empty cpusets when hotplug happens * and take masks of ancestors with non-empty cpus/mems, instead of * being moved to an ancestor.
@@ -468,6 +471,13 @@ struct cftype {#endif }; +extern struct cgroup_root cgrp_dfl_root; + +static inline bool cgroup_on_dfl (const struct cgroup *cgrp) +{ +return cgrp->root == &cgrp_dfl_root; +} +/* * See the comment above CGRP_ROOT_SANE_BEHAVIOR for details. This * function can be called as long as @cgrp is accessible.
kernel/cgroup.c +61 -33
169 lines not on this page · raw message
Signature · 1 line
1.8.5.3
PATCH 11/11 cgroup: implement CFTYPE_ONLY_ON_DFL
In reply to a message not in the archiveThis cftype flag makes the file only appear on the default hierarchy. This will later be used for cgroup.controllers file.
--- include/linux/cgroup.h | 1 + kernel/cgroup.c | 2 ++ 2 files changed, 3 insertions(+)
include/linux/cgroup.h +1 -0
@@ -384,6 +384,7 @@ enum {CFTYPE_NOT_ON_ROOT = (1 <<1 ),/* don't create on root cgrp */ CFTYPE_INSANE = (1 <<2 ),/* don't create if sane_behavior */ CFTYPE_NO_PREFIX = (1 <<3 ),/* (DON'T USE FOR NEW FILES) no subsys prefix */ + CFTYPE_ONLY_ON_DFL = (1 << 4), /* only on default hierarchy */ };#define MAX_CFTYPE_NAME 64
kernel/cgroup.c +2 -0
@@ -2356,6 +2356,8 @@ static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[],for (cft = cfts; cft->name[0 ] !='\0' ; cft++) {/* does cft->flags tell us to skip this file on @cgrp? */ +if ((cft->flags &CFTYPE_ONLY_ON_DFL ) && !cgroup_on_dfl (cgrp)) +continue ;if ((cft->flags &CFTYPE_INSANE ) &&cgroup_sane_behavior (cgrp))continue ;if ((cft->flags &CFTYPE_NOT_ON_ROOT ) && !cgrp->parent)
Signature · 1 line
1.8.5.3
Li Zefan
Acked-byQuoted 44 lines · Tejun Heo
Hello,
The planned unified hierarchy is just around the corner. We're gonna repurpose the dummy hierarchy to serve as the default unified hierarchy. Controllers which aren't attached to other hierarchies are already automatically bound to the dummy hierarchy; however, the dummy hierarchy is minimally initialized during boot and can't currently act as a full hierarchy.
This patchset gradually turns the dummy hierarchy into fully functional default one and makes it mountable via selecting
sane_behaviorwithout any subsystems specified. While this patchset does make the default hierarchy mountable, the unified hierarchy functionality isn't implemented yet and cgroup creation in the default hierarchy is rejected for now.This lays down all the boilerplate work for the unified hierarchy. The next patchset will implement the actual unified functionality.
This patchset contains the following eleven patches.
0001-cgroup-cgroup-subsys-should-be-cleared-after-the-css.patch 0002-cgroup-relocate-setting-of-CGRP_DEAD.patch 0003-cgroup-reorganize-cgroup-bootstrapping.patch 0004-cgroup-use-cgroup_setup_root-to-initialize-cgroup_du.patch 0005-cgroup-remove-NULL-checks-from-pr_cont_-cgroup_-name.patch 0006-cgroup-treat-cgroup_dummy_root-as-an-equivalent-hier.patch 0007-cgroup-move-subsys_mask-from-cgroupfs_root-to-cgroup.patch 0008-cgroup-rename-cgroup_dummy_root-and-related-names.patch 0009-cgroup-drop-const-from-buffer-of-cftype-write_string.patch 0010-cgroup-make-cgrp_dfl_root-mountable.patch 0011-cgroup-implement-CFTYPE_ONLY_ON_DFL.patch
0001-0002 are misc fix / prep.
0003-0009 (mostly) turn the dummy hierarchy into a full hierarchy which takes on controllers which aren't attached to other hierarchies.
0010-0011 make the default hierarchy mountable and implement
CFTYPE_ONLY_DFL.This patchset is on top of cgroup/for-3.15
b8dadcb58d54("cpuset: usercu_read_lock()to protecttask_cs()"). diffstat follows.
Quoted 13 lines
block/blk-throttle.c | 4 block/cfq-iosched.c | 4 include/linux/cgroup.h | 57 ++--- kernel/cgroup.c | 464 +++++++++++++++++++++++++--------------------- kernel/cgroup_freezer.c | 2 kernel/cpuset.c | 2 mm/hugetlb_cgroup.c | 2 mm/memcontrol.c | 4 net/core/netprio_cgroup.c | 2 net/ipv4/tcp_memcontrol.c | 2 security/device_cgroup.c | 4 11 files changed, 295 insertions(+), 252 deletions(-)
Looks good in general!
Tejun Heo
maintainerPATCH 4/11 cgroup: use cgroup_setup_root() to initialize cgroup_dummy_root
In reply to Tejun Heocgroup_dummy_root is used to host controllers which aren't attached to any other hierarchy. The root is minimally set up during kernfs bootstrap and didn't go through full hierarchy initialization. We're planning to use cgroup_dummy_root for the default unified hierarchy and thus want it to be fully functional.
Replace the special initialization, which was collected into cgroup_init() by the previous patch, with an invocation of cgroup_setup_root(). This simplifies the init path and makes cgroup_dummy_root a full hierarchy with its own kernfs_root and all.
As this puts the dummy hierarchy on the cgroup_roots list, rename for_each_active_root() to for_each_root() and update its users to skip the dummy root for now.
This patch doesn't cause any userland visible behavior changes at this point.
--- kernel/cgroup.c | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-)
kernel/cgroup.c +20 -23
@@ -289,8 +289,8 @@ static int notify_on_release(const struct cgroup *cgrp)for ((ssid) =0 ; (ssid) <CGROUP_SUBSYS_COUNT && \ (((ss) = cgroup_subsys[ssid]) || true); (ssid)++) -/* iterate across the active hierarchies */ -#define for_each_active_root (root) \ +/* iterate across the hierarchies */ +#define for_each_root (root) \ list_for_each_entry((root), &cgroup_roots, root_list)/**
@@ -354,7 +354,6 @@ static struct css_set init_css_set = { .mg_node = LIST_HEAD_INIT(init_css_set.mg_node), }; -static struct cgrp_cset_link init_cgrp_cset_link;static int css_set_count =1 ;/* 1 for init_css_set */ /*
@@ -693,14 +692,13 @@ static struct cgroupfs_root *cgroup_root_from_kf(struct kernfs_root *kf_root)return top_cgrp->root; } -static int cgroup_init_root_id (struct cgroupfs_root *root,int start,int end) +static int cgroup_init_root_id (struct cgroupfs_root *root) {int id;lockdep_assert_held (&cgroup_mutex); - id =idr_alloc_cyclic (&cgroup_hierarchy_idr, root, start, end, -GFP_KERNEL ); + id =idr_alloc_cyclic (&cgroup_hierarchy_idr, root,0 ,0 ,GFP_KERNEL );if (id <0 )return id;
@@ -1405,8 +1403,7 @@ static int cgroup_setup_root(struct cgroupfs_root *root, unsigned long ss_mask)if (ret) goto out; -/* ID 0 is reserved for dummy root, 1 for unified hierarchy */ - ret =cgroup_init_root_id (root,2 ,0 ); + ret =cgroup_init_root_id (root);if (ret) goto out;
@@ -1486,9 +1483,12 @@ retry: goto out_unlock;/* look for a matching existing root */ -for_each_active_root (root) { +for_each_root (root) {bool name_match = false; +if (root == &cgroup_dummy_root) +continue ; +/* * If we asked for a name then it must match. Also, if * name matches but sybsys_mask doesn't, we should fail.
@@ -2106,9 +2106,12 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk)int retval =0 ;mutex_lock (&cgroup_mutex); -for_each_active_root (root) { +for_each_root (root) {struct cgroup *from_cgrp; +if (root == &cgroup_dummy_root) +continue ; +down_read (&css_set_rwsem); from_cgrp =task_cgroup_from_root (from, root);up_read (&css_set_rwsem);
@@ -4073,26 +4076,17 @@ int __init cgroup_init(void)BUG_ON (cgroup_init_cftypes (NULL , cgroup_base_files)); -/* allocate id for the dummy hierarchy */ +mutex_lock (&cgroup_tree_mutex);mutex_lock (&cgroup_mutex);/* 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 (cgroup_init_root_id (&cgroup_dummy_root,0 ,1 )); - - err =idr_alloc (&cgroup_dummy_root.cgroup_idr, cgroup_dummy_top, -0 ,1 ,GFP_KERNEL ); -BUG_ON (err <0 ); - - cgroup_root_count =1 ; - init_cgrp_cset_link.cset = &init_css_set; - init_cgrp_cset_link.cgrp = cgroup_dummy_top; -list_add (&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links); -list_add (&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links); +BUG_ON (cgroup_setup_root (&cgroup_dummy_root,0 ));mutex_unlock (&cgroup_mutex); +mutex_unlock (&cgroup_tree_mutex);for_each_subsys (ss, ssid) {if (!ss->early_init)
@@ -4176,11 +4170,14 @@ int proc_cgroup_show(struct seq_file *m, void *v)mutex_lock (&cgroup_mutex);down_read (&css_set_rwsem); -for_each_active_root (root) { +for_each_root (root) {struct cgroup_subsys *ss;struct cgroup *cgrp;int ssid, count =0 ; +if (root == &cgroup_dummy_root) +continue ; +seq_printf (m,"%d:" , root->hierarchy_id);for_each_subsys (ss, ssid)if (root->subsys_mask & (1 << ssid))
Signature · 1 line
1.8.5.3
Tejun Heo
maintainerPATCH 5/11 cgroup: remove NULL checks from [pr_cont_]cgroup_{name|path}()
In reply to Tejun HeoThe dummy hierarchy is now a fully functional one and dummy_top has a kernfs_node associated with it. Drop the NULL checks in [pr_cont_]cont_{name|path}() which are no longer necessary.
--- include/linux/cgroup.h | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-)
include/linux/cgroup.h +4 -20
@@ -508,39 +508,23 @@ struct cgroup_subsys_state *seq_css(struct seq_file *seq);static inline int cgroup_name (struct cgroup *cgrp,char *buf,size_t buflen) { -/* dummy_top doesn't have a kn associated */ -if (cgrp->kn) -return kernfs_name (cgrp->kn, buf, buflen); -else -return strlcpy (buf,"/" , buflen); +return kernfs_name (cgrp->kn, buf, buflen); }static inline char *__must_check cgroup_path (struct cgroup *cgrp,char *buf,size_t buflen) { -/* dummy_top doesn't have a kn associated */ -if (cgrp->kn) -return kernfs_path (cgrp->kn, buf, buflen); -strlcpy (buf,"/" , buflen); -return (buflen <=2 ) ?NULL : buf; +return kernfs_path (cgrp->kn, buf, buflen); }static inline void pr_cont_cgroup_name (struct cgroup *cgrp) { -/* dummy_top doesn't have a kn associated */ -if (cgrp->kn) -pr_cont_kernfs_name (cgrp->kn); -else -pr_cont ("/" ); +pr_cont_kernfs_name (cgrp->kn); }static inline void pr_cont_cgroup_path (struct cgroup *cgrp) { -/* dummy_top doesn't have a kn associated */ -if (cgrp->kn) -pr_cont_kernfs_path (cgrp->kn); -else -pr_cont ("/" ); +pr_cont_kernfs_path (cgrp->kn); }char *task_cgroup_path (struct task_struct *task,char *buf,size_t buflen);
Signature · 1 line
1.8.5.3
Tejun Heo
maintainerPATCH 6/11 cgroup: treat cgroup_dummy_root as an equivalent hierarchy during rebinding
In reply to Tejun HeoCurrently, while rebinding, cgroup_dummy_root serves as the anchor point. In addition to the target root, rebind_subsystems() takes @added_mask and @removed_mask. The subsystems specified in the former are expected to be on the dummy root and then moved to the target root. The ones in the latter are moved from non-dummy root to dummy. Now that the dummy root is a fully functional one and we're planning to use it for the default unified hierarchy, this level of distinction between dummy and non-dummy roots is quite awkward.
This patch updates rebind_subsystems() to take the target root and one subsystem mask and move the specified subsystmes to the target root which may or may not be the dummy root. IOW, unbinding now becomes moving the subsystems to the dummy root and binding to non-dummy root. This makes the dummy root mostly equivalent to other hierarchies in terms of the mechanism of moving subsystems around; however, we still retain all the semantical restrictions so that this patch doesn't introduce any visible behavior differences. Another noteworthy detail is that rebind_subsystems() guarantees that moving a subsystem to the dummy root never fails so that valid unmounting attempts always succeed.
This unifies binding and unbinding of subsystems. The invocation points of ->bind() were inconsistent between the two and now moved after whole rebinding is complete. This doesn't break the current users and generally makes more sense.
All rebind_subsystems() users are converted accordingly. Note that cgroup_remount() now makes two calls to rebind_subsystems() to bind and then unbind the requested subsystems.
This will allow repurposing of the dummy hierarchy as the default unified hierarchy and shouldn't make any userland visible behavior difference.
--- kernel/cgroup.c | 100 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 44 deletions(-)
kernel/cgroup.c +56 -44
@@ -175,8 +175,8 @@ static int need_forkexit_callback __read_mostly;static struct cftype cgroup_base_files[];static void cgroup_put (struct cgroup *cgrp); -static int rebind_subsystems (struct cgroupfs_root *root, -unsigned long added_mask,unsigned removed_mask); +static int rebind_subsystems (struct cgroupfs_root *dst_root, +unsigned long ss_mask);static void cgroup_destroy_css_killed (struct cgroup *cgrp);static int cgroup_destroy_locked (struct cgroup *cgrp); static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[],
@@ -739,7 +739,7 @@ static void cgroup_destroy_root(struct cgroupfs_root *root)BUG_ON (!list_empty (&cgrp->children));/* Rebind all subsystems back to the default hierarchy */ -WARN_ON (rebind_subsystems (root,0 , root->subsys_mask)); +rebind_subsystems (&cgroup_dummy_root, root->subsys_mask);/* * Release all the links from cset_links to this hierarchy's
@@ -976,69 +976,77 @@ static void cgroup_clear_dir(struct cgroup *cgrp, unsigned long subsys_mask) } } -static int rebind_subsystems (struct cgroupfs_root *root, -unsigned long added_mask,unsigned removed_mask) +static int rebind_subsystems (struct cgroupfs_root *dst_root, +unsigned long ss_mask) { -struct cgroup *cgrp = &root->top_cgroup; +struct cgroup *dst_top = &dst_root->top_cgroup;struct cgroup_subsys *ss; -int i, ret; +int ssid, ret;lockdep_assert_held (&cgroup_tree_mutex);lockdep_assert_held (&cgroup_mutex); -/* Check that any added subsystems are currently free */ -for_each_subsys (ss, i) -if ((added_mask & (1 << i)) && ss->root != &cgroup_dummy_root) +for_each_subsys (ss, ssid) { +if (!(ss_mask & (1 << ssid))) +continue ; + +/* if @ss is on the dummy_root, we can always move it */ +if (ss->root == &cgroup_dummy_root) +continue ; + +/* if @ss has non-root cgroups attached to it, can't move */ +if (!list_empty (&ss->root->top_cgroup.children))return -EBUSY ; - ret =cgroup_populate_dir (cgrp, added_mask); -if (ret) -return ret; +/* can't move between two non-dummy roots either */ +if (dst_root != &cgroup_dummy_root) +return -EBUSY ; + } + +if (dst_root != &cgroup_dummy_root) { + ret =cgroup_populate_dir (dst_top, ss_mask); +if (ret) +return ret; + }/* * Nothing can fail from this point on. Remove files for the * removed subsystems and rebind each subsystem. */ mutex_unlock (&cgroup_mutex); -cgroup_clear_dir (cgrp, removed_mask); +for_each_subsys (ss, ssid) +if ((ss_mask & (1 << ssid)) && ss->root != &cgroup_dummy_root) +cgroup_clear_dir (&ss->root->top_cgroup,1 << ssid);mutex_lock (&cgroup_mutex); -for_each_subsys (ss, i) { -unsigned long bit =1UL << i; - -if (bit & added_mask) { -/* We're binding this subsystem to this hierarchy */ -BUG_ON (cgroup_css (cgrp, ss)); -BUG_ON (!cgroup_css (cgroup_dummy_top, ss)); -BUG_ON (cgroup_css (cgroup_dummy_top, ss)->cgroup != cgroup_dummy_top); +for_each_subsys (ss, ssid) { +struct cgroupfs_root *src_root; +struct cgroup *src_top; +struct cgroup_subsys_state *css; -rcu_assign_pointer (cgrp->subsys[i], -cgroup_css (cgroup_dummy_top, ss)); -cgroup_css (cgrp, ss)->cgroup = cgrp; +if (!(ss_mask & (1 << ssid))) +continue ; - ss->root = root; -if (ss->bind) - ss->bind (cgroup_css (cgrp, ss)); + src_root = ss->root; + src_top = &src_root->top_cgroup; + css =cgroup_css (src_top, ss); -/* refcount was already taken, and we're keeping it */ - root->subsys_mask |= bit; - }else if (bit & removed_mask) { -/* We're removing this subsystem */ -BUG_ON (cgroup_css (cgrp, ss) !=cgroup_css (cgroup_dummy_top, ss)); -BUG_ON (cgroup_css (cgrp, ss)->cgroup != cgrp); +WARN_ON (!css ||cgroup_css (dst_top, ss)); -if (ss->bind) - ss->bind (cgroup_css (cgroup_dummy_top, ss)); +RCU_INIT_POINTER (src_top->subsys[ssid],NULL ); +rcu_assign_pointer (dst_top->subsys[ssid], css); + ss->root = dst_root; + css->cgroup = dst_top; -cgroup_css (cgroup_dummy_top, ss)->cgroup = cgroup_dummy_top; -RCU_INIT_POINTER (cgrp->subsys[i],NULL ); + src_root->subsys_mask &= ~(1 << ssid); + dst_root->subsys_mask |=1 << ssid; - cgroup_subsys[i]->root = &cgroup_dummy_root; - root->subsys_mask &= ~bit; - } +if (ss->bind) + ss->bind (css); } -kernfs_activate (cgrp->kn); +if (dst_root != &cgroup_dummy_root) +kernfs_activate (dst_top->kn);return 0 ; }
@@ -1277,10 +1285,12 @@ static int cgroup_remount(struct kernfs_root *kf_root, int *flags, char *data) goto out_unlock; } - ret =rebind_subsystems (root, added_mask, removed_mask); + ret =rebind_subsystems (root, added_mask);if (ret) goto out_unlock; +rebind_subsystems (&cgroup_dummy_root, removed_mask); +if (opts.release_agent) {spin_lock (&release_agent_path_lock);strcpy (root->release_agent_path, opts.release_agent);
@@ -1420,7 +1430,7 @@ static int cgroup_setup_root(struct cgroupfs_root *root, unsigned long ss_mask)if (ret) goto destroy_root; - ret =rebind_subsystems (root, ss_mask,0 ); + ret =rebind_subsystems (root, ss_mask);if (ret) goto destroy_root;
@@ -4026,6 +4036,8 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)BUG_ON (online_css (css)); + cgroup_dummy_root.subsys_mask |=1 << ss->id; +mutex_unlock (&cgroup_mutex);mutex_unlock (&cgroup_tree_mutex); }
Signature · 1 line
1.8.5.3
Tejun Heo
maintainerPATCH 7/11 cgroup: move ->subsys_mask from cgroupfs_root to cgroup
In reply to Tejun Heocgroupfs_root->subsys_mask represents the controllers attached to the hierarchy. This patch moves the field to cgroup. Subsystem initialization and rebinding updates the top cgroup's subsys_mask. For !root cgroups, the subsys_mask bits are set from create_css() and cleared from kill_css(), which effectively means that all cgroups will have the same subsys_mask as the top cgroup.
While this doesn't make any difference now, this will help implementation of the default unified hierarchy where !root cgroups may have subsets of the top_cgroup's subsys_mask.
While at it, __kill_css() is split out of kill_css(). The former doesn't care about the subsys_mask while the latter becomes noop if the controller is already killed and clears the matching bit if not before proceeding to killing the css. This will be used later by the default unified hierarchy implementation.
--- include/linux/cgroup.h | 6 ++--- kernel/cgroup.c | 61 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 42 insertions(+), 25 deletions(-)
include/linux/cgroup.h +3 -3
@@ -173,6 +173,9 @@ struct cgroup {*/ u64 serial_nr; +/* The bitmask of subsystems attached to this cgroup */ +unsigned long subsys_mask; +/* Private pointers for each registered subsystem */ struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT ];
@@ -276,9 +279,6 @@ enum {struct cgroupfs_root {struct kernfs_root *kf_root; -/* The bitmask of subsystems attached to this hierarchy */ -unsigned long subsys_mask; -/* Unique id for this hierarchy. */ int hierarchy_id;
kernel/cgroup.c +39 -22
137 lines not on this page · raw message
Signature · 1 line
1.8.5.3
Tejun Heo
maintainerPATCH 8/11 cgroup: rename cgroup_dummy_root and related names
In reply to Tejun HeoThe dummy root will be repurposed to serve as the default unified hierarchy. Let's rename things in preparation.
* s/cgroup_dummy_root/cgrp_dfl_root/
* s/cgroupfs_root/cgroup_root/ as we don't do fs part directly anymore
* s/cgroup_root->top_cgroup/cgroup_root->cgrp/ for brevity
This is pure rename.
--- include/linux/cgroup.h | 14 ++--- kernel/cgroup.c | 168 ++++++++++++++++++++++++------------------------- 2 files changed, 88 insertions(+), 94 deletions(-)
include/linux/cgroup.h +7 -7
@@ -24,7 +24,7 @@#ifdef CONFIG_CGROUPS -struct cgroupfs_root ; +struct cgroup_root ;struct cgroup_subsys ;struct inode ;struct cgroup ;
@@ -179,7 +179,7 @@ struct cgroup {/* Private pointers for each registered subsystem */ struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT ]; -struct cgroupfs_root *root; +struct cgroup_root *root;/* * List of cgrp_cset_links pointing at css_sets with tasks in this
@@ -211,7 +211,7 @@ struct cgroup {#define MAX_CGROUP_ROOT_NAMELEN 64 -/* cgroupfs_root->flags */ +/* cgroup_root->flags */ enum {/* * Unfortunately, cgroup core and various controllers are riddled
@@ -272,18 +272,18 @@ enum { };/* -* A cgroupfs_root represents the root of a cgroup hierarchy, and may be +* A cgroup_root represents the root of a cgroup hierarchy, and may be * associated with a kernfs_root to form an active hierarchy. This is * internal to cgroup core. Don't access directly from controllers. */ -struct cgroupfs_root { +struct cgroup_root {struct kernfs_root *kf_root;/* Unique id for this hierarchy. */ int hierarchy_id;/* The root cgroup. Root is destroyed on its release. */ -struct cgroup top_cgroup; +struct cgroup cgrp;/* Number of cgroups in the hierarchy, used only for /proc/cgroups */ atomic_t nr_cgrps;
@@ -598,7 +598,7 @@ struct cgroup_subsys {const char *name;/* link to parent, protected by cgroup_lock() */ -struct cgroupfs_root *root; +struct cgroup_root *root;/* * List of cftypes. Each entry is the first entry of an array
kernel/cgroup.c +81 -87
517 lines not on this page · raw message
Signature · 1 line
1.8.5.3
Tejun Heo
maintainerPATCH 9/11 cgroup: drop const from @buffer of cftype->write_string()
In reply to Tejun Heocftype->write_string() just passes on the writeable buffer from kernfs and there's no reason to add const restriction on the buffer. The only thing const achieves is unnecessarily complicating parsing of the buffer. Drop const from @buffer.
--- block/blk-throttle.c | 4 ++-- block/cfq-iosched.c | 4 ++-- include/linux/cgroup.h | 2 +- kernel/cgroup.c | 2 +- kernel/cgroup_freezer.c | 2 +- kernel/cpuset.c | 2 +- mm/hugetlb_cgroup.c | 2 +- mm/memcontrol.c | 4 ++-- net/core/netprio_cgroup.c | 2 +- net/ipv4/tcp_memcontrol.c | 2 +- security/device_cgroup.c | 4 ++-- 11 files changed, 15 insertions(+), 15 deletions(-)
block/blk-throttle.c +2 -2
@@ -1408,13 +1408,13 @@ static int tg_set_conf(struct cgroup_subsys_state *css, struct cftype *cft, }static int tg_set_conf_u64 (struct cgroup_subsys_state *css,struct cftype *cft, -const char *buf) +char *buf) {return tg_set_conf (css, cft, buf, true); }static int tg_set_conf_uint (struct cgroup_subsys_state *css,struct cftype *cft, -const char *buf) +char *buf) {return tg_set_conf (css, cft, buf, false); }
block/cfq-iosched.c +2 -2
@@ -1701,13 +1701,13 @@ static int __cfqg_set_weight_device(struct cgroup_subsys_state *css, }static int cfqg_set_weight_device (struct cgroup_subsys_state *css, -struct cftype *cft,const char *buf) +struct cftype *cft,char *buf) {return __cfqg_set_weight_device (css, cft, buf, false); }static int cfqg_set_leaf_weight_device (struct cgroup_subsys_state *css, -struct cftype *cft,const char *buf) +struct cftype *cft,char *buf) {return __cfqg_set_weight_device (css, cft, buf, true); }
include/linux/cgroup.h +1 -1
@@ -454,7 +454,7 @@ struct cftype {* Returns 0 or -ve error code. */ int (*write_string)(struct cgroup_subsys_state *css,struct cftype *cft, -const char *buffer); +char *buffer);/* * trigger() callback can be used to get some kick from the * userspace, when the actual string written is not important
kernel/cgroup.c +1 -1
@@ -2143,7 +2143,7 @@ static int cgroup_procs_write(struct cgroup_subsys_state *css, }static int cgroup_release_agent_write (struct cgroup_subsys_state *css, -struct cftype *cft,const char *buffer) +struct cftype *cft,char *buffer) {struct cgroup_root *root = css->cgroup->root;
kernel/cgroup_freezer.c +1 -1
@@ -442,7 +442,7 @@ static void freezer_change_state(struct freezer *freezer, bool freeze) }static int freezer_write (struct cgroup_subsys_state *css,struct cftype *cft, -const char *buffer) +char *buffer) {bool freeze;
kernel/cpuset.c +1 -1
@@ -1610,7 +1610,7 @@ out_unlock:* Common handling for a write to a "cpus" or "mems" file. */ static int cpuset_write_resmask (struct cgroup_subsys_state *css, -struct cftype *cft,const char *buf) +struct cftype *cft,char *buf) {struct cpuset *cs =css_cs (css);struct cpuset *trialcs;
mm/hugetlb_cgroup.c +1 -1
@@ -254,7 +254,7 @@ static u64 hugetlb_cgroup_read_u64(struct cgroup_subsys_state *css, }static int hugetlb_cgroup_write (struct cgroup_subsys_state *css, -struct cftype *cft,const char *buffer) +struct cftype *cft,char *buffer) {int idx, name, ret;unsigned long long val;
mm/memcontrol.c +2 -2
@@ -5242,7 +5242,7 @@ static int memcg_update_kmem_limit(struct mem_cgroup *memcg,* RES_LIMIT. */ static int mem_cgroup_write (struct cgroup_subsys_state *css,struct cftype *cft, -const char *buffer) +char *buffer) {struct mem_cgroup *memcg =mem_cgroup_from_css (css);enum res_type type;
@@ -6063,7 +6063,7 @@ static void memcg_event_ptable_queue_proc(struct file *file,* Interpretation of args is defined by control file implementation. */ static int memcg_write_event_control (struct cgroup_subsys_state *css, -struct cftype *cft,const char *buffer) +struct cftype *cft,char *buffer) {struct mem_cgroup *memcg =mem_cgroup_from_css (css);struct mem_cgroup_event *event;
net/core/netprio_cgroup.c +1 -1
@@ -186,7 +186,7 @@ static int read_priomap(struct seq_file *sf, void *v) }static int write_priomap (struct cgroup_subsys_state *css,struct cftype *cft, -const char *buffer) +char *buffer) {char devname[IFNAMSIZ +1 ];struct net_device *dev;
net/ipv4/tcp_memcontrol.c +1 -1
@@ -103,7 +103,7 @@ static int tcp_update_limit(struct mem_cgroup *memcg, u64 val) }static int tcp_cgroup_write (struct cgroup_subsys_state *css,struct cftype *cft, -const char *buffer) +char *buffer) {struct mem_cgroup *memcg =mem_cgroup_from_css (css);unsigned long long val;
security/device_cgroup.c +2 -2
@@ -496,7 +496,7 @@ static inline bool has_children(struct dev_cgroup *devcgroup)* parent cgroup has the access you're asking for. */ static int devcgroup_update_access (struct dev_cgroup *devcgroup, -int filetype,const char *buffer) +int filetype,char *buffer) {const char *b;char temp[12 ];/* 11 + 1 characters needed for a u32 */
@@ -652,7 +652,7 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, }static int devcgroup_access_write (struct cgroup_subsys_state *css, -struct cftype *cft,const char *buffer) +struct cftype *cft,char *buffer) {int retval;
Signature · 1 line
1.8.5.3
Tejun Heo
maintainerPATCH 10/11 cgroup: make cgrp_dfl_root mountable
In reply to Tejun Heocgrp_dfl_root will be used as the default unified hierarchy. This patch makes cgrp_dfl_root mountable by making the following changes.
* cgroup_init_early() now initializes cgrp_dfl_root w/ CGRP_ROOT_SANE_BEHAVIOR. The default hierarchy is always sane.
* parse_cgroupfs_options() and cgroup_mount() are updated such that cgrp_dfl_root is mounted if sane_behavior is specified w/o any subsystems.
* rebind_subsystems() now populates the root directory of cgrp_dfl_root. Note that the function still guarantees success of rebinding subsystems to cgrp_dfl_root. If populating fails while rebinding to cgrp_dfl_root, it whines but ignores the error.
* For backward compatibility, the default hierarchy shows up in /proc/$PID/cgroup only after it's explicitly mounted so that userland which doesn't make use of it doesn't see any change.
* "current_css_set_cg_links" file of debug cgroup now treats the default hierarchy the same as other hierarchies. This is visible to userland. Given that it's for debug controller, this should be fine.
* While at it, implement cgroup_on_dfl() which tests whether a give cgroup is on the default hierarchy or not.
The above changes make cgrp_dfl_root mostly equivalent to other controllers but the actual unified hierarchy behaviors are not implemented yet. Let's plug child cgroup creation in cgrp_dfl_root from create_cgroup() for now.
--- include/linux/cgroup.h | 10 ++++++ kernel/cgroup.c | 94 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 71 insertions(+), 33 deletions(-)
include/linux/cgroup.h +10 -0
@@ -250,6 +250,9 @@ enum {* * - "cgroup.clone_children" is removed. * +* - If mount is requested with sane_behavior but without any +* subsystem, the default unified hierarchy is mounted. +* * - cpuset: tasks will be kept in empty cpusets when hotplug happens * and take masks of ancestors with non-empty cpus/mems, instead of * being moved to an ancestor.
@@ -468,6 +471,13 @@ struct cftype {#endif }; +extern struct cgroup_root cgrp_dfl_root; + +static inline bool cgroup_on_dfl (const struct cgroup *cgrp) +{ +return cgrp->root == &cgrp_dfl_root; +} +/* * See the comment above CGRP_ROOT_SANE_BEHAVIOR for details. This * function can be called as long as @cgrp is accessible.
kernel/cgroup.c +61 -33
169 lines not on this page · raw message
Signature · 1 line
1.8.5.3
Tejun Heo
maintainerPATCH 11/11 cgroup: implement CFTYPE_ONLY_ON_DFL
In reply to Tejun HeoThis cftype flag makes the file only appear on the default hierarchy. This will later be used for cgroup.controllers file.
--- include/linux/cgroup.h | 1 + kernel/cgroup.c | 2 ++ 2 files changed, 3 insertions(+)
include/linux/cgroup.h +1 -0
@@ -384,6 +384,7 @@ enum {CFTYPE_NOT_ON_ROOT = (1 <<1 ),/* don't create on root cgrp */ CFTYPE_INSANE = (1 <<2 ),/* don't create if sane_behavior */ CFTYPE_NO_PREFIX = (1 <<3 ),/* (DON'T USE FOR NEW FILES) no subsys prefix */ + CFTYPE_ONLY_ON_DFL = (1 << 4), /* only on default hierarchy */ };#define MAX_CFTYPE_NAME 64
kernel/cgroup.c +2 -0
@@ -2356,6 +2356,8 @@ static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[],for (cft = cfts; cft->name[0 ] !='\0' ; cft++) {/* does cft->flags tell us to skip this file on @cgrp? */ +if ((cft->flags &CFTYPE_ONLY_ON_DFL ) && !cgroup_on_dfl (cgrp)) +continue ;if ((cft->flags &CFTYPE_INSANE ) &&cgroup_sane_behavior (cgrp))continue ;if ((cft->flags &CFTYPE_NOT_ON_ROOT ) && !cgrp->parent)
Signature · 1 line
1.8.5.3
Quoted 44 lines · Tejun Heo
Hello,
The planned unified hierarchy is just around the corner. We're gonna repurpose the dummy hierarchy to serve as the default unified hierarchy. Controllers which aren't attached to other hierarchies are already automatically bound to the dummy hierarchy; however, the dummy hierarchy is minimally initialized during boot and can't currently act as a full hierarchy.
This patchset gradually turns the dummy hierarchy into fully functional default one and makes it mountable via selecting
sane_behaviorwithout any subsystems specified. While this patchset does make the default hierarchy mountable, the unified hierarchy functionality isn't implemented yet and cgroup creation in the default hierarchy is rejected for now.This lays down all the boilerplate work for the unified hierarchy. The next patchset will implement the actual unified functionality.
This patchset contains the following eleven patches.
0001-cgroup-cgroup-subsys-should-be-cleared-after-the-css.patch 0002-cgroup-relocate-setting-of-CGRP_DEAD.patch 0003-cgroup-reorganize-cgroup-bootstrapping.patch 0004-cgroup-use-cgroup_setup_root-to-initialize-cgroup_du.patch 0005-cgroup-remove-NULL-checks-from-pr_cont_-cgroup_-name.patch 0006-cgroup-treat-cgroup_dummy_root-as-an-equivalent-hier.patch 0007-cgroup-move-subsys_mask-from-cgroupfs_root-to-cgroup.patch 0008-cgroup-rename-cgroup_dummy_root-and-related-names.patch 0009-cgroup-drop-const-from-buffer-of-cftype-write_string.patch 0010-cgroup-make-cgrp_dfl_root-mountable.patch 0011-cgroup-implement-CFTYPE_ONLY_ON_DFL.patch
0001-0002 are misc fix / prep.
0003-0009 (mostly) turn the dummy hierarchy into a full hierarchy which takes on controllers which aren't attached to other hierarchies.
0010-0011 make the default hierarchy mountable and implement
CFTYPE_ONLY_DFL.This patchset is on top of cgroup/for-3.15
b8dadcb58d54("cpuset: usercu_read_lock()to protecttask_cs()"). diffstat follows.
Quoted 13 lines
block/blk-throttle.c | 4 block/cfq-iosched.c | 4 include/linux/cgroup.h | 57 ++--- kernel/cgroup.c | 464 +++++++++++++++++++++++++--------------------- kernel/cgroup_freezer.c | 2 kernel/cpuset.c | 2 mm/hugetlb_cgroup.c | 2 mm/memcontrol.c | 4 net/core/netprio_cgroup.c | 2 net/ipv4/tcp_memcontrol.c | 2 security/device_cgroup.c | 4 11 files changed, 295 insertions(+), 252 deletions(-)
Looks good in general!
Tejun Heo
maintainerQuoted 19 lines · Tejun Heo
The planned unified hierarchy is just around the corner. We're gonna repurpose the dummy hierarchy to serve as the default unified hierarchy. Controllers which aren't attached to other hierarchies are already automatically bound to the dummy hierarchy; however, the dummy hierarchy is minimally initialized during boot and can't currently act as a full hierarchy.
This patchset gradually turns the dummy hierarchy into fully functional default one and makes it mountable via selecting
sane_behaviorwithout any subsystems specified. While this patchset does make the default hierarchy mountable, the unified hierarchy functionality isn't implemented yet and cgroup creation in the default hierarchy is rejected for now.This lays down all the boilerplate work for the unified hierarchy. The next patchset will implement the actual unified functionality.
This patchset contains the following eleven patches.
Quoted 11 lines
0001-cgroup-cgroup-subsys-should-be-cleared-after-the-css.patch 0002-cgroup-relocate-setting-of-CGRP_DEAD.patch 0003-cgroup-reorganize-cgroup-bootstrapping.patch 0004-cgroup-use-cgroup_setup_root-to-initialize-cgroup_du.patch 0005-cgroup-remove-NULL-checks-from-pr_cont_-cgroup_-name.patch 0006-cgroup-treat-cgroup_dummy_root-as-an-equivalent-hier.patch 0007-cgroup-move-subsys_mask-from-cgroupfs_root-to-cgroup.patch 0008-cgroup-rename-cgroup_dummy_root-and-related-names.patch 0009-cgroup-drop-const-from-buffer-of-cftype-write_string.patch 0010-cgroup-make-cgrp_dfl_root-mountable.patch 0011-cgroup-implement-CFTYPE_ONLY_ON_DFL.patch
Applied 0002-0011 to libata/for-3.15. 0001 has the possibility to make css iterators malfunction as they don't exect the csses to be NULL. It will be applied after iterators are updated to handle NULL csses.
Thanks.
Signature · 1 line
tejun