cgroup: reorganize cgroup source files
Subsystems (2)
Tejun Heo
maintainerPATCH 1/1 cgroup: reorganize cgroup source files
cgroup source files are getting a bit too unwieldy. Let's reorganize them.
* Move cgroup files in kernel to kernel/cgroup.
* Split cgroup.c into multiple files.
The only functional change this patchset causes is loss of a WARN_ON(); otherwise, everything remains identical.
This patchset contains the following eight patches.
0001-cgroup-reorder-css_set-fields.patch 0002-cgroup-move-cgroup-files-under-kernel-cgroup.patch 0003-cgroup-move-cgroup-v1-specific-code-to-kernel-cgroup.patch 0004-cgroup-refactor-mount-path-and-clearly-distinguish-v.patch 0005-cgroup-separate-out-cgroup1_kf_syscall_ops.patch 0006-cgroup-move-v1-mount-functions-to-kernel-cgroup-cgro.patch 0007-cgroup-rename-functions-for-consistency.patch 0008-cgroup-move-namespace-code-to-kernel-cgroup-namespac.patch
The patchset is available in the following git branch
git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git review-cgroup-reorg
and on top of the following git branch
git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git review-cgroup2-procs
diffstat follows. Thanks.
include/linux/cgroup-defs.h | 54 - kernel/Makefile | 5 kernel/cgroup/Makefile | 5 kernel/cgroup/cgroup-internal.h | 155 +++ kernel/cgroup/cgroup-v1.c | 1395 ++++++++++++++++++++++++++++ kernel/cgroup/cgroup.c | 1940 +++------------------------------------- kernel/cgroup/namespace.c | 155 +++ 7 files changed, 1907 insertions(+), 1802 deletions(-)
--
tejun
Tejun Heo
maintainerPATCH 1/8 cgroup: reorder css_set fields
Reorder css_set fields so that they're roughly in the order of how hot they are. The rough order is
1. the actual csses
2. reference counter and the default cgroup pointer.
3. task lists and iterations
4. fields used during merge including css_set lookup
5. the rest
--- include/linux/cgroup-defs.h | 54 ++++++++++++++++++++++----------------------- kernel/cgroup.c | 13 ++++++----- 2 files changed, 35 insertions(+), 32 deletions(-)
include/linux/cgroup-defs.h +27 -27
@@ -148,14 +148,18 @@ struct cgroup_subsys_state {* set for a task. */ struct css_set { -/* Reference count */ -atomic_t refcount; -/* -* List running through all cgroup groups in the same hash -* slot. Protected by css_set_lock +* 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). */ -struct hlist_node hlist; +struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT ]; + +/* reference count */ +atomic_t refcount; + +/* the default cgroup associated with this css_set */ +struct cgroup *dfl_cgrp;/* * Lists running through all tasks using this cgroup group.
@@ -167,21 +171,29 @@ struct css_set {struct list_head tasks;struct list_head mg_tasks; +/* all css_task_iters currently walking this cset */ +struct list_head task_iters; +/* -* List of cgrp_cset_links pointing at cgroups referenced from this -* css_set. Protected by css_set_lock. +* On the default hierarhcy, ->subsys[ssid] may point to a css +* attached to an ancestor instead of the cgroup this css_set is +* associated with. The following node is anchored at +* ->subsys[ssid]->cgroup->e_csets[ssid] and provides a way to +* iterate through all css's attached to a given cgroup. */ -struct list_head cgrp_links; +struct list_head e_cset_node[CGROUP_SUBSYS_COUNT ]; -/* the default cgroup associated with this css_set */ -struct cgroup *dfl_cgrp; +/* +* List running through all cgroup groups in the same hash +* slot. Protected by css_set_lock +*/ +struct hlist_node hlist;/* -* 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). +* List of cgrp_cset_links pointing at cgroups referenced from this +* css_set. Protected by css_set_lock. */ -struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT ]; +struct list_head cgrp_links;/* * List of csets participating in the on-going migration either as
@@ -201,18 +213,6 @@ struct css_set {struct cgroup *mg_dst_cgrp;struct css_set *mg_dst_cset; -/* -* On the default hierarhcy, ->subsys[ssid] may point to a css -* attached to an ancestor instead of the cgroup this css_set is -* associated with. The following node is anchored at -* ->subsys[ssid]->cgroup->e_csets[ssid] and provides a way to -* iterate through all css's attached to a given cgroup. -*/ -struct list_head e_cset_node[CGROUP_SUBSYS_COUNT ]; - -/* all css_task_iters currently walking this cset */ -struct list_head task_iters; -/* dead and being drained, ignore for migration */ bool dead;
kernel/cgroup.c +8 -5
@@ -647,12 +647,12 @@ struct cgrp_cset_link {*/ 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), + .task_iters =LIST_HEAD_INIT (init_css_set.task_iters), + .cgrp_links =LIST_HEAD_INIT (init_css_set.cgrp_links), .mg_preload_node =LIST_HEAD_INIT (init_css_set.mg_preload_node), .mg_node =LIST_HEAD_INIT (init_css_set.mg_node), - .task_iters =LIST_HEAD_INIT (init_css_set.task_iters), };static int css_set_count =1 ;/* 1 for init_css_set */
@@ -1095,13 +1095,13 @@ static struct css_set *find_css_set(struct css_set *old_cset, }atomic_set (&cset->refcount,1 ); -INIT_LIST_HEAD (&cset->cgrp_links);INIT_LIST_HEAD (&cset->tasks);INIT_LIST_HEAD (&cset->mg_tasks); -INIT_LIST_HEAD (&cset->mg_preload_node); -INIT_LIST_HEAD (&cset->mg_node);INIT_LIST_HEAD (&cset->task_iters);INIT_HLIST_NODE (&cset->hlist); +INIT_LIST_HEAD (&cset->cgrp_links); +INIT_LIST_HEAD (&cset->mg_preload_node); +INIT_LIST_HEAD (&cset->mg_node);/* Copy the set of subsystem state objects generated in * find_existing_css_set() */
@@ -4384,6 +4384,9 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)struct task_struct *task;int ret; +if (cgroup_on_dfl (to)) +return -EINVAL ; +if (!cgroup_may_migrate_to (to))return -EBUSY ;
Signature · 1 line
2.9.3
Tejun Heo
maintainerPATCH 2/8 cgroup: move cgroup files under kernel/cgroup/
In reply to Tejun HeoThey're growing to be too many and planned to get split further. Move them under their own directory.
kernel/cgroup.c -> kernel/cgroup/cgroup.c
kernel/cgroup_freezer.c -> kernel/cgroup/freezer.c
kernel/cgroup_pids.c -> kernel/cgroup/pids.c
kernel/cpuset.c -> kernel/cgroup/cpuset.c
---
kernel/Makefile | 5 +----
kernel/cgroup/Makefile | 5 +++++
kernel/{ => cgroup}/cgroup.c | 0
kernel/{ => cgroup}/cpuset.c | 0
kernel/{cgroup_freezer.c => cgroup/freezer.c} | 0
kernel/{cgroup_pids.c => cgroup/pids.c} | 0
6 files changed, 6 insertions(+), 4 deletions(-)
create mode 100644 kernel/cgroup/Makefile
rename kernel/{ => cgroup}/cgroup.c (100%)
rename kernel/{ => cgroup}/cpuset.c (100%)
rename kernel/{cgroup_freezer.c => cgroup/freezer.c} (100%)
rename kernel/{cgroup_pids.c => cgroup/pids.c} (100%)kernel/Makefile +1 -4
@@ -64,10 +64,7 @@ obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_KEXEC_FILE) += kexec_file.o obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o obj-$(CONFIG_COMPAT) += compat.o -obj-$(CONFIG_CGROUPS) += cgroup.o -obj-$(CONFIG_CGROUP_FREEZER) += cgroup_freezer.o -obj-$(CONFIG_CGROUP_PIDS) += cgroup_pids.o -obj-$(CONFIG_CPUSETS) += cpuset.o +obj-$(CONFIG_CGROUPS) += cgroup/ obj-$(CONFIG_UTS_NS) += utsname.o obj-$(CONFIG_USER_NS) += user_namespace.o obj-$(CONFIG_PID_NS) += pid_namespace.o
kernel/cgroup/Makefile new file +5 -0
@@ -0,0 +1,5 @@ +obj-y := cgroup.o + +obj-$(CONFIG_CGROUP_FREEZER) += freezer.o +obj-$(CONFIG_CGROUP_PIDS) += pids.o +obj-$(CONFIG_CPUSETS) += cpuset.o
kernel/cgroup/cgroup.c renamed from kernel/cgroup.c +0 -0
kernel/cgroup/cpuset.c renamed from kernel/cpuset.c +0 -0
kernel/cgroup/freezer.c renamed from kernel/cgroup_freezer.c +0 -0
kernel/cgroup/pids.c renamed from kernel/cgroup_pids.c +0 -0
Signature · 1 line
2.9.3
Tejun Heo
maintainerPATCH 3/8 cgroup: move cgroup v1 specific code to kernel/cgroup/cgroup-v1.c
In reply to Tejun Heocgroup.c is getting too unwieldy. Let's move out cgroup v1 specific code along with the debug controller into kernel/cgroup/cgroup-v1.c.
--- kernel/cgroup/Makefile | 2 +- kernel/cgroup/cgroup-internal.h | 101 ++++ kernel/cgroup/cgroup-v1.c | 1027 +++++++++++++++++++++++++++++++++++ kernel/cgroup/cgroup.c | 1134 ++------------------------------------- 4 files changed, 1160 insertions(+), 1104 deletions(-) create mode 100644 kernel/cgroup/cgroup-internal.h create mode 100644 kernel/cgroup/cgroup-v1.c
kernel/cgroup/Makefile +1 -1
@@ -1,4 +1,4 @@ -obj-y := cgroup.o +obj-y := cgroup.o cgroup-v1.o obj-$(CONFIG_CGROUP_FREEZER) += freezer.o obj-$(CONFIG_CGROUP_PIDS) += pids.o
kernel/cgroup/cgroup-internal.h new file +101 -0
101 lines not on this page · raw message
kernel/cgroup/cgroup-v1.c new file +1027 -0
1,027 lines not on this page · raw message
kernel/cgroup/cgroup.c +31 -1103
1,410 lines not on this page · raw message
Signature · 1 line
2.9.3
Tejun Heo
maintainerPATCH v2 3/8 cgroup: move cgroup v1 specific code to kernel/cgroup/cgroup-v1.c
From 738c8be934e713c7841f49adaece8d7afa0e9166 Mon Sep 17 00:00:00 2001
From: Tejun Heo <[email protected]>
Date: Tue, 20 Dec 2016 16:59:05 -0500
cgroup.c is getting too unwieldy. Let's move out cgroup v1 specific code along with the debug controller into kernel/cgroup/cgroup-v1.c.
v2: cgroup_mutex and css_set_lock made available in cgroup-internal.h
regardless of CONFIG_PROVE_RCU.
--- kernel/cgroup/Makefile | 2 +- kernel/cgroup/cgroup-internal.h | 103 ++++ kernel/cgroup/cgroup-v1.c | 1027 +++++++++++++++++++++++++++++++++++ kernel/cgroup/cgroup.c | 1140 ++------------------------------------- 4 files changed, 1164 insertions(+), 1108 deletions(-) create mode 100644 kernel/cgroup/cgroup-internal.h create mode 100644 kernel/cgroup/cgroup-v1.c
kernel/cgroup/Makefile +1 -1
@@ -1,4 +1,4 @@ -obj-y := cgroup.o +obj-y := cgroup.o cgroup-v1.o obj-$(CONFIG_CGROUP_FREEZER) += freezer.o obj-$(CONFIG_CGROUP_PIDS) += pids.o
kernel/cgroup/cgroup-internal.h new file +103 -0
103 lines not on this page · raw message
kernel/cgroup/cgroup-v1.c new file +1027 -0
1,027 lines not on this page · raw message
kernel/cgroup/cgroup.c +33 -1107
1,426 lines not on this page · raw message
Signature · 1 line
2.9.3
Tejun Heo
maintainerPATCH 4/8 cgroup: refactor mount path and clearly distinguish v1 and v2 paths
In reply to Tejun HeoWhile sharing some mechanisms, the mount paths of v1 and v2 are substantially different. Their implementations were mixed in cgroup_mount(). This patch splits them out so that they're easier to follow and organize.
This patch causes one functional change - the WARN_ON(new_sb) gets lost. This is because the actual mounting gets moved to cgroup_do_mount() and thus @new_sb is no longer accessible by default to cgroup1_mount(). While we can add it as an explicit out parameter to cgroup_do_mount(), this part of code hasn't changed and the warning hasn't triggered for quite a while. Dropping it should be fine.
--- kernel/cgroup/cgroup.c | 140 ++++++++++++++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 61 deletions(-)
kernel/cgroup/cgroup.c +79 -61
@@ -1991,48 +1991,55 @@ static int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)return ret; } -static struct dentry *cgroup_mount (struct file_system_type *fs_type, -int flags,const char *unused_dev_name, -void *data) +static struct dentry *cgroup_do_mount (struct file_system_type *fs_type, +int flags,struct cgroup_root *root, +unsigned long magic, +struct cgroup_namespace *ns) { -bool is_v2 = fs_type == &cgroup2_fs_type; -struct super_block *pinned_sb =NULL ; -struct cgroup_namespace *ns = current->nsproxy->cgroup_ns; -struct cgroup_subsys *ss; -struct cgroup_root *root; -struct cgroup_sb_opts opts;struct dentry *dentry; -int ret; -int i;bool new_sb; -get_cgroup_ns (ns); - -/* Check if the caller has permission to mount. */ -if (!ns_capable (ns->user_ns,CAP_SYS_ADMIN )) { -put_cgroup_ns (ns); -return ERR_PTR (-EPERM ); - } + dentry =kernfs_mount (fs_type, flags, root->kf_root, magic, &new_sb);/* -* The first time anyone tries to mount a cgroup, enable the list -* linking each css_set to its tasks and fix up all existing tasks. +* In non-init cgroup namespace, instead of root cgroup's dentry, +* we return the dentry corresponding to the cgroupns->root_cgrp. */ -if (!use_task_css_set_links) -cgroup_enable_task_cg_lists (); +if (!IS_ERR (dentry) && ns != &init_cgroup_ns) { +struct dentry *nsdentry; +struct cgroup *cgrp; -if (is_v2) { -if (data) { -pr_err ("cgroup2: unknown option \"%s\"\n" , (char *)data); -put_cgroup_ns (ns); -return ERR_PTR (-EINVAL ); - } - cgrp_dfl_visible = true; - root = &cgrp_dfl_root; -cgroup_get (&root->cgrp); - goto out_mount; +mutex_lock (&cgroup_mutex); +spin_lock_irq (&css_set_lock); + + cgrp =cset_cgroup_from_root (ns->root_cset, root); + +spin_unlock_irq (&css_set_lock); +mutex_unlock (&cgroup_mutex); + + nsdentry =kernfs_node_dentry (cgrp->kn, dentry->d_sb); +dput (dentry); + dentry = nsdentry; } +if (IS_ERR (dentry) || !new_sb) +cgroup_put (&root->cgrp); + +return dentry; +} + +static struct dentry *cgroup1_mount (struct file_system_type *fs_type, +int flags,void *data, +unsigned long magic, +struct cgroup_namespace *ns) +{ +struct super_block *pinned_sb =NULL ; +struct cgroup_sb_opts opts; +struct cgroup_root *root; +struct cgroup_subsys *ss; +struct dentry *dentry; +int i, ret; +cgroup_lock_and_drain_offline (&cgrp_dfl_root.cgrp);/* First find the desired set of subsystems */
@@ -2154,47 +2161,58 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,kfree (opts.release_agent);kfree (opts.name); -if (ret) { -put_cgroup_ns (ns); +if (ret)return ERR_PTR (ret); - } -out_mount: - dentry =kernfs_mount (fs_type, flags, root->kf_root, - is_v2 ?CGROUP2_SUPER_MAGIC :CGROUP_SUPER_MAGIC , - &new_sb); + + dentry =cgroup_do_mount (&cgroup_fs_type, flags, root, +CGROUP_SUPER_MAGIC , ns);/* -* In non-init cgroup namespace, instead of root cgroup's -* dentry, we return the dentry corresponding to the -* cgroupns->root_cgrp. +* If @pinned_sb, we're reusing an existing root and holding an +* extra ref on its sb. Mount is complete. Put the extra ref. */ -if (!IS_ERR (dentry) && ns != &init_cgroup_ns) { -struct dentry *nsdentry; -struct cgroup *cgrp; +if (pinned_sb) +deactivate_super (pinned_sb); -mutex_lock (&cgroup_mutex); -spin_lock_irq (&css_set_lock); +return dentry; +} - cgrp =cset_cgroup_from_root (ns->root_cset, root); +static struct dentry *cgroup_mount (struct file_system_type *fs_type, +int flags,const char *unused_dev_name, +void *data) +{ +struct cgroup_namespace *ns = current->nsproxy->cgroup_ns; +struct dentry *dentry; -spin_unlock_irq (&css_set_lock); -mutex_unlock (&cgroup_mutex); +get_cgroup_ns (ns); - nsdentry =kernfs_node_dentry (cgrp->kn, dentry->d_sb); -dput (dentry); - dentry = nsdentry; +/* Check if the caller has permission to mount. */ +if (!ns_capable (ns->user_ns,CAP_SYS_ADMIN )) { +put_cgroup_ns (ns); +return ERR_PTR (-EPERM ); } -if (IS_ERR (dentry) || !new_sb) -cgroup_put (&root->cgrp); -/* -* If @pinned_sb, we're reusing an existing root and holding an -* extra ref on its sb. Mount is complete. Put the extra ref. +* The first time anyone tries to mount a cgroup, enable the list +* linking each css_set to its tasks and fix up all existing tasks. */ -if (pinned_sb) { -WARN_ON (new_sb); -deactivate_super (pinned_sb); +if (!use_task_css_set_links) +cgroup_enable_task_cg_lists (); + +if (fs_type == &cgroup2_fs_type) { +if (data) { +pr_err ("cgroup2: unknown option \"%s\"\n" , (char *)data); +put_cgroup_ns (ns); +return ERR_PTR (-EINVAL ); + } + cgrp_dfl_visible = true; +cgroup_get (&cgrp_dfl_root.cgrp); + + dentry =cgroup_do_mount (&cgroup2_fs_type, flags, &cgrp_dfl_root, +CGROUP2_SUPER_MAGIC , ns); + }else { + dentry =cgroup1_mount (&cgroup_fs_type, flags, data, +CGROUP_SUPER_MAGIC , ns); }put_cgroup_ns (ns);
Signature · 1 line
2.9.3
Tejun Heo
maintainerPATCH 5/8 cgroup: separate out cgroup1_kf_syscall_ops
In reply to Tejun HeoCurrently, cgroup_kf_syscall_ops is shared by v1 and v2 and the specific methods test the version and take different actions. Split out v1 functions and put them in cgroup1_kf_syscall_ops and remove the now unnecessary explicit branches in specific methods.
--- kernel/cgroup/cgroup-internal.h | 4 ++-- kernel/cgroup/cgroup-v1.c | 11 ++--------- kernel/cgroup/cgroup.c | 40 ++++++++++++++++++++++++++-------------- 3 files changed, 30 insertions(+), 25 deletions(-)
kernel/cgroup/cgroup-internal.h +2 -2
@@ -93,8 +93,8 @@ extern const struct file_operations proc_cgroupstats_operations;bool cgroup_ssid_no_v1 (int ssid);void cgroup_pidlist_destroy_all (struct cgroup *cgrp); -int cgroup_rename (struct kernfs_node *kn,struct kernfs_node *new_parent, -const char *new_name_str); +int cgroup1_rename (struct kernfs_node *kn,struct kernfs_node *new_parent, +const char *new_name_str);void cgroup_release_agent (struct work_struct *work);void check_for_release (struct cgroup *cgrp);
kernel/cgroup/cgroup-v1.c +2 -9
@@ -800,8 +800,8 @@ void cgroup_release_agent(struct work_struct *work)/* * cgroup_rename - Only allow simple rename of directories in place. */ -int cgroup_rename (struct kernfs_node *kn,struct kernfs_node *new_parent, -const char *new_name_str) +int cgroup1_rename (struct kernfs_node *kn,struct kernfs_node *new_parent, +const char *new_name_str) {struct cgroup *cgrp = kn->priv;int ret;
@@ -812,13 +812,6 @@ int cgroup_rename(struct kernfs_node *kn, struct kernfs_node *new_parent,return -EIO ;/* -* This isn't a proper migration and its usefulness is very -* limited. Disallow on the default hierarchy. -*/ -if (cgroup_on_dfl (cgrp)) -return -EPERM ; - -/* * We're gonna grab cgroup_mutex which nests outside kernfs * active_ref. kernfs_rename() doesn't require active_ref * protection. Break them before grabbing cgroup_mutex.
kernel/cgroup/cgroup.c +26 -14
@@ -1234,6 +1234,7 @@ struct cgroup *task_cgroup_from_root(struct task_struct *task,* update of a tasks cgroup pointer by cgroup_attach_task() */ +static struct kernfs_syscall_ops cgroup1_kf_syscall_ops;static struct kernfs_syscall_ops cgroup_kf_syscall_ops; static char *cgroup_file_name(struct cgroup *cgrp, const struct cftype *cft,
@@ -1568,16 +1569,15 @@ static int cgroup_show_path(struct seq_file *sf, struct kernfs_node *kf_node,return len; } -static int cgroup_show_options (struct seq_file *seq,struct kernfs_root *kf_root) +static int cgroup1_show_options (struct seq_file *seq,struct kernfs_root *kf_root) {struct cgroup_root *root =cgroup_root_from_kf (kf_root);struct cgroup_subsys *ss;int ssid; -if (root != &cgrp_dfl_root) -for_each_subsys (ss, ssid) -if (root->subsys_mask & (1 << ssid)) -seq_show_option (seq, ss->legacy_name,NULL ); +for_each_subsys (ss, ssid) +if (root->subsys_mask & (1 << ssid)) +seq_show_option (seq, ss->legacy_name,NULL );if (root->flags &CGRP_ROOT_NOPREFIX )seq_puts (seq,",noprefix" );if (root->flags &CGRP_ROOT_XATTR )
@@ -1738,18 +1738,13 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)return 0 ; } -static int cgroup_remount (struct kernfs_root *kf_root,int *flags,char *data) +static int cgroup1_remount (struct kernfs_root *kf_root,int *flags,char *data) {int ret =0 ;struct cgroup_root *root =cgroup_root_from_kf (kf_root);struct cgroup_sb_opts opts;u16 added_mask, removed_mask; -if (root == &cgrp_dfl_root) { -pr_err ("remount is not allowed\n" ); -return -EINVAL ; - } -cgroup_lock_and_drain_offline (&cgrp_dfl_root.cgrp);/* See what subsystems are wanted */
@@ -1800,6 +1795,12 @@ static int cgroup_remount(struct kernfs_root *kf_root, int *flags, char *data)return ret; } +static int cgroup_remount (struct kernfs_root *kf_root,int *flags,char *data) +{ +pr_err ("remount is not allowed\n" ); +return -EINVAL ; +} +/* * To reduce the fork() overhead for systems that are not actually using * their cgroups capability, we don't maintain the lists running through
@@ -1902,6 +1903,7 @@ static int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask) {LIST_HEAD (tmp_links);struct cgroup *root_cgrp = &root->cgrp; +struct kernfs_syscall_ops *kf_sops;struct css_set *cset;int i, ret;
@@ -1933,7 +1935,10 @@ static int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)if (ret) goto cancel_ref; - root->kf_root =kernfs_create_root (&cgroup_kf_syscall_ops, + kf_sops = root == &cgrp_dfl_root ? + &cgroup_kf_syscall_ops : &cgroup1_kf_syscall_ops; + + root->kf_root =kernfs_create_root (kf_sops,KERNFS_ROOT_CREATE_DEACTIVATED , root_cgrp);if (IS_ERR (root->kf_root)) {
@@ -4815,12 +4820,19 @@ static int cgroup_rmdir(struct kernfs_node *kn)return ret; } +static struct kernfs_syscall_ops cgroup1_kf_syscall_ops = { + .remount_fs = cgroup1_remount, + .show_options = cgroup1_show_options, + .rename = cgroup1_rename, + .mkdir = cgroup_mkdir, + .rmdir = cgroup_rmdir, + .show_path = cgroup_show_path, +}; +static struct kernfs_syscall_ops cgroup_kf_syscall_ops = { .remount_fs = cgroup_remount, - .show_options = cgroup_show_options, .mkdir = cgroup_mkdir, .rmdir = cgroup_rmdir, - .rename = cgroup_rename, .show_path = cgroup_show_path, };
Signature · 1 line
2.9.3
Tejun Heo
maintainerPATCH 6/8 cgroup: move v1 mount functions to kernel/cgroup/cgroup-v1.c
In reply to Tejun HeoNow that the v1 mount code is split into separate functions, move them to kernel/cgroup/cgroup-v1.c along with the mount option handling code. As this puts all v1-only kernfs_syscall_ops in cgroup-v1.c, move cgroup1_kf_syscall_ops to cgroup-v1.c too.
--- kernel/cgroup/cgroup-internal.h | 28 ++- kernel/cgroup/cgroup-v1.c | 381 ++++++++++++++++++++++++++++++++++++- kernel/cgroup/cgroup.c | 410 +--------------------------------------- 3 files changed, 413 insertions(+), 406 deletions(-)
kernel/cgroup/cgroup-internal.h +25 -3
@@ -26,6 +26,16 @@ struct cgrp_cset_link {struct list_head cgrp_link; }; +struct cgroup_sb_opts { +u16 subsys_mask; +unsigned int flags; +char *release_agent; +bool cpuset_clone_children; +char *name; +/* User explicitly requested empty subsystem */ +bool none; +}; +extern struct cgroup_subsys *cgroup_subsys[];extern struct list_head cgroup_roots;extern struct file_system_type cgroup_fs_type;
@@ -64,7 +74,13 @@ void cgroup_kn_unlock(struct kernfs_node *kn);int cgroup_path_ns_locked (struct cgroup *cgrp,char *buf,size_t buflen,struct cgroup_namespace *ns); +void cgroup_free_root (struct cgroup_root *root); +void init_cgroup_root (struct cgroup_root *root,struct cgroup_sb_opts *opts); +int cgroup_setup_root (struct cgroup_root *root,u16 ss_mask);int rebind_subsystems (struct cgroup_root *dst_root,u16 ss_mask); +struct dentry *cgroup_do_mount (struct file_system_type *fs_type,int flags, +struct cgroup_root *root,unsigned long magic, +struct cgroup_namespace *ns);bool cgroup_may_migrate_to (struct cgroup *dst_cgrp);void cgroup_migrate_finish (struct list_head *preloaded_csets);
@@ -84,18 +100,24 @@ ssize_t cgroup_procs_write(struct kernfs_open_file *of, char *buf, size_t nbytesvoid cgroup_lock_and_drain_offline (struct cgroup *cgrp); +int cgroup_mkdir (struct kernfs_node *parent_kn,const char *name,umode_t mode); +int cgroup_rmdir (struct kernfs_node *kn); +int cgroup_show_path (struct seq_file *sf,struct kernfs_node *kf_node, +struct kernfs_root *kf_root); +/* * cgroup-v1.c */ -extern spinlock_t release_agent_path_lock;extern struct cftype cgroup_legacy_base_files[];extern const struct file_operations proc_cgroupstats_operations; +extern struct kernfs_syscall_ops cgroup1_kf_syscall_ops;bool cgroup_ssid_no_v1 (int ssid);void cgroup_pidlist_destroy_all (struct cgroup *cgrp); -int cgroup1_rename (struct kernfs_node *kn,struct kernfs_node *new_parent, -const char *new_name_str);void cgroup_release_agent (struct work_struct *work);void check_for_release (struct cgroup *cgrp); +struct dentry *cgroup1_mount (struct file_system_type *fs_type,int flags, +void *data,unsigned long magic, +struct cgroup_namespace *ns);#endif /* __CGROUP_INTERNAL_H */
kernel/cgroup/cgroup-v1.c +378 -3
406 lines not on this page · raw message
kernel/cgroup/cgroup.c +10 -400
488 lines not on this page · raw message
Signature · 1 line
2.9.3
Tejun Heo
maintainerPATCH 7/8 cgroup: rename functions for consistency
In reply to Tejun HeoNow that v1 functions are separated out, rename some functions for consistency.
cgroup_dfl_base_files -> cgroup_base_files
cgroup_legacy_base_files -> cgroup1_base_files
cgroup_ssid_no_v1() -> cgroup1_ssid_disabled()
cgroup_pidlist_destroy_all -> cgroup1_pidlist_destroy_all()
cgroup_release_agent() -> cgroup1_release_agent()
check_for_release() -> cgroup1_check_for_release()
--- kernel/cgroup/cgroup-internal.h | 10 +++++----- kernel/cgroup/cgroup-v1.c | 14 +++++++------- kernel/cgroup/cgroup.c | 22 +++++++++++----------- 3 files changed, 23 insertions(+), 23 deletions(-)
kernel/cgroup/cgroup-internal.h +5 -5
@@ -108,14 +108,14 @@ int cgroup_show_path(struct seq_file *sf, struct kernfs_node *kf_node,/* * cgroup-v1.c */ -extern struct cftype cgroup_legacy_base_files[]; +extern struct cftype cgroup1_base_files[];extern const struct file_operations proc_cgroupstats_operations;extern struct kernfs_syscall_ops cgroup1_kf_syscall_ops; -bool cgroup_ssid_no_v1 (int ssid); -void cgroup_pidlist_destroy_all (struct cgroup *cgrp); -void cgroup_release_agent (struct work_struct *work); -void check_for_release (struct cgroup *cgrp); +bool cgroup1_ssid_disabled (int ssid); +void cgroup1_pidlist_destroy_all (struct cgroup *cgrp); +void cgroup1_release_agent (struct work_struct *work); +void cgroup1_check_for_release (struct cgroup *cgrp);struct dentry *cgroup1_mount (struct file_system_type *fs_type,int flags,void *data,unsigned long magic,struct cgroup_namespace *ns);
kernel/cgroup/cgroup-v1.c +7 -7
@@ -36,7 +36,7 @@ static struct workqueue_struct *cgroup_pidlist_destroy_wq;*/ static DEFINE_SPINLOCK (release_agent_path_lock); -bool cgroup_ssid_no_v1 (int ssid) +bool cgroup1_ssid_disabled (int ssid) {return cgroup_no_v1_mask & (1 << ssid); }
@@ -201,7 +201,7 @@ static void pidlist_free(void *p)* Used to destroy all pidlists lingering waiting for destroy timer. None * should be left afterwards. */ -void cgroup_pidlist_destroy_all (struct cgroup *cgrp) +void cgroup1_pidlist_destroy_all (struct cgroup *cgrp) {struct cgroup_pidlist *l, *tmp_l;
@@ -585,7 +585,7 @@ static int cgroup_clone_children_write(struct cgroup_subsys_state *css, }/* cgroup core interface files for the legacy hierarchies */ -struct cftype cgroup_legacy_base_files[] = { +struct cftype cgroup1_base_files[] = { { .name ="cgroup.procs" , .seq_start = cgroup_pidlist_start,
@@ -729,7 +729,7 @@ int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry)return 0 ; } -void check_for_release (struct cgroup *cgrp) +void cgroup1_check_for_release (struct cgroup *cgrp) {if (notify_on_release (cgrp) && !cgroup_is_populated (cgrp) && !css_has_online_children (&cgrp->self) && !cgroup_is_dead (cgrp))
@@ -759,7 +759,7 @@ void check_for_release(struct cgroup *cgrp)* this routine has no use for the exit status of the release agent * task, so no sense holding our caller up for that. */ -void cgroup_release_agent (struct work_struct *work) +void cgroup1_release_agent (struct work_struct *work) {struct cgroup *cgrp = container_of(work, struct cgroup, release_agent_work);
@@ -946,7 +946,7 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)continue ;if (!cgroup_ssid_enabled (i))continue ; -if (cgroup_ssid_no_v1 (i)) +if (cgroup1_ssid_disabled (i))continue ;/* Mutually exclusive option 'all' + subsystem name */
@@ -968,7 +968,7 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)*/ if (all_ss || (!one_ss && !opts->none && !opts->name))for_each_subsys (ss, i) -if (cgroup_ssid_enabled (i) && !cgroup_ssid_no_v1 (i)) +if (cgroup_ssid_enabled (i) && !cgroup1_ssid_disabled (i)) opts->subsys_mask |= (1 << i);/*
kernel/cgroup/cgroup.c +11 -11
@@ -201,7 +201,7 @@ struct cgroup_namespace init_cgroup_ns = {static u16 have_canfork_callback__read_mostly ;static struct file_system_type cgroup2_fs_type; -static struct cftype cgroup_dfl_base_files[]; +static struct cftype cgroup_base_files[];static int cgroup_apply_control (struct cgroup *cgrp);static void cgroup_finalize_control (struct cgroup *cgrp,int ret);
@@ -611,7 +611,7 @@ static void cgroup_update_populated(struct cgroup *cgrp, bool populated)if (!trigger)break ; -check_for_release (cgrp); +cgroup1_check_for_release (cgrp);cgroup_file_notify (&cgrp->events_file); cgrp =cgroup_parent (cgrp);
@@ -1442,9 +1442,9 @@ static int css_populate_dir(struct cgroup_subsys_state *css)if (!css->ss) {if (cgroup_on_dfl (cgrp)) - cfts = cgroup_dfl_base_files; + cfts = cgroup_base_files;else - cfts = cgroup_legacy_base_files; + cfts = cgroup1_base_files;return cgroup_addrm_files (&cgrp->self, cgrp, cfts, true); }
@@ -1647,7 +1647,7 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp)INIT_LIST_HEAD (&cgrp->e_csets[ssid]);init_waitqueue_head (&cgrp->offline_waitq); -INIT_WORK (&cgrp->release_agent_work, cgroup_release_agent); +INIT_WORK (&cgrp->release_agent_work, cgroup1_release_agent); }void init_cgroup_root (struct cgroup_root *root,struct cgroup_sb_opts *opts)
@@ -3838,7 +3838,7 @@ static int cgroup_procs_show(struct seq_file *s, void *v) }/* cgroup core interface files for the default hierarchy */ -static struct cftype cgroup_dfl_base_files[] = { +static struct cftype cgroup_base_files[] = { { .name ="cgroup.procs" , .file_offset = offsetof(struct cgroup , procs_file),
@@ -3911,7 +3911,7 @@ static void css_free_work_fn(struct work_struct *work) }else {/* cgroup free path */ atomic_dec (&cgrp->root->nr_cgrps); -cgroup_pidlist_destroy_all (cgrp); +cgroup1_pidlist_destroy_all (cgrp);cancel_work_sync (&cgrp->release_agent_work);if (cgroup_parent (cgrp)) {
@@ -4413,7 +4413,7 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)*/ kernfs_remove (cgrp->kn); -check_for_release (cgroup_parent (cgrp)); +cgroup1_check_for_release (cgroup_parent (cgrp));/* put the base reference */ percpu_ref_kill (&cgrp->self.refcnt);
@@ -4550,8 +4550,8 @@ int __init cgroup_init(void)BUILD_BUG_ON (CGROUP_SUBSYS_COUNT >16 );BUG_ON (percpu_init_rwsem (&cgroup_threadgroup_rwsem)); -BUG_ON (cgroup_init_cftypes (NULL , cgroup_dfl_base_files)); -BUG_ON (cgroup_init_cftypes (NULL , cgroup_legacy_base_files)); +BUG_ON (cgroup_init_cftypes (NULL , cgroup_base_files)); +BUG_ON (cgroup_init_cftypes (NULL , cgroup1_base_files));/* * The latency of the synchronize_sched() is too high for cgroups,
@@ -4601,7 +4601,7 @@ int __init cgroup_init(void)continue ; } -if (cgroup_ssid_no_v1 (ssid)) +if (cgroup1_ssid_disabled (ssid))printk (KERN_INFO "Disabling %s control group subsystem in v1 mounts\n" , ss->name);
Signature · 1 line
2.9.3
Tejun Heo
maintainerPATCH 8/8 cgroup: move namespace code to kernel/cgroup/namespace.c
In reply to Tejun Heoget/put_css_set() get exposed in cgroup-internal.h in the process.
--- kernel/cgroup/Makefile | 2 +- kernel/cgroup/cgroup-internal.h | 32 ++++++++ kernel/cgroup/cgroup.c | 175 +--------------------------------------- kernel/cgroup/namespace.c | 155 +++++++++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+), 175 deletions(-) create mode 100644 kernel/cgroup/namespace.c
kernel/cgroup/Makefile +1 -1
@@ -1,4 +1,4 @@ -obj-y := cgroup.o cgroup-v1.o +obj-y := cgroup.o namespace.o cgroup-v1.o obj-$(CONFIG_CGROUP_FREEZER) += freezer.o obj-$(CONFIG_CGROUP_PIDS) += pids.o
kernel/cgroup/cgroup-internal.h +32 -0
@@ -63,6 +63,33 @@ static inline bool notify_on_release(const struct cgroup *cgrp)return test_bit (CGRP_NOTIFY_ON_RELEASE , &cgrp->flags); } +void put_css_set_locked (struct css_set *cset); + +static inline void put_css_set (struct css_set *cset) +{ +unsigned long flags; + +/* +* Ensure that the refcount doesn't hit zero while any readers +* can see it. Similar to atomic_dec_and_lock(), but for an +* rwlock +*/ +if (atomic_add_unless (&cset->refcount,-1 ,1 )) +return ; + +spin_lock_irqsave (&css_set_lock, flags); +put_css_set_locked (cset); +spin_unlock_irqrestore (&css_set_lock, flags); +} + +/* +* refcounted get/put for css_set objects +*/ +static inline void get_css_set (struct css_set *cset) +{ +atomic_inc (&cset->refcount); +} +bool cgroup_ssid_enabled (int ssid);bool cgroup_on_dfl (const struct cgroup *cgrp);
@@ -106,6 +133,11 @@ int cgroup_show_path(struct seq_file *sf, struct kernfs_node *kf_node, struct kernfs_root *kf_root);/* +* namespace.c +*/ +extern const struct proc_ns_operations cgroupns_operations; + +/* * cgroup-v1.c */ extern struct cftype cgroup1_base_files[];
kernel/cgroup/cgroup.c +1 -174
193 lines not on this page · raw message
kernel/cgroup/namespace.c new file +155 -0
155 lines not on this page · raw message
Signature · 1 line
2.9.3
Tejun Heo
maintainer[PATCH 9/8] cgroup: fix RCU related sparse warnings
In reply to Tejun HeoFrom 9ca76e7e3cb885bc5701e9b1fe90c44f4aef123a Mon Sep 17 00:00:00 2001
From: Tejun Heo <[email protected]>
Date: Thu, 22 Dec 2016 12:28:01 -0500
kn->priv which is a void * is used as a RCU pointer by cgroup. When dereferencing it, it was passing kn->priv to rcu_derefreence() without casting it into a RCU pointer triggering address space mismatch warning from sparse. Fix them.
--- kernel/cgroup/cgroup-v1.c | 2 +- kernel/cgroup/cgroup.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
kernel/cgroup/cgroup-v1.c +1 -1
@@ -694,7 +694,7 @@ int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry)* @kn->priv is RCU safe. Let's do the RCU dancing. */ rcu_read_lock (); - cgrp =rcu_dereference (kn->priv); + cgrp =rcu_dereference (*(void __rcu __force **)&kn->priv);if (!cgrp ||cgroup_is_dead (cgrp)) {rcu_read_unlock ();mutex_unlock (&cgroup_mutex);
kernel/cgroup/cgroup.c +1 -1
@@ -4932,7 +4932,7 @@ struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry,* have been or be removed at any point. @kn->priv is RCU * protected for this access. See css_release_work_fn() for details. */ - cgrp =rcu_dereference (kn->priv); + cgrp =rcu_dereference (*(void __rcu __force **)&kn->priv);if (cgrp) css =cgroup_css (cgrp, ss);
Signature · 1 line
2.9.3
Quoted 31 lines · Tejun Heo
cgroup source files are getting a bit too unwieldy. Let's reorganize them.
* Move cgroup files in kernel to kernel/cgroup.
* Split
cgroup.cinto multiple files.The only functional change this patchset causes is loss of a
WARN_ON(); otherwise, everything remains identical.This patchset contains the following eight patches.
0001-cgroup-reorder-css_set-fields.patch 0002-cgroup-move-cgroup-files-under-kernel-cgroup.patch 0003-cgroup-move-cgroup-v1-specific-code-to-kernel-cgroup.patch 0004-cgroup-refactor-mount-path-and-clearly-distinguish-v.patch 0005-cgroup-separate-out-cgroup1_kf_syscall_ops.patch 0006-cgroup-move-v1-mount-functions-to-kernel-cgroup-cgro.patch 0007-cgroup-rename-functions-for-consistency.patch 0008-cgroup-move-namespace-code-to-kernel-cgroup-namespac.patch
The patchset is available in the following git branch
git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.gitreview-cgroup-reorgand on top of the following git branch
git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.gitreview-cgroup2-procsdiffstat follows. Thanks.
Quoted 9 lines
include/linux/cgroup-defs.h | 54 - kernel/Makefile | 5 kernel/cgroup/Makefile | 5 kernel/cgroup/cgroup-internal.h | 155 +++ kernel/cgroup/cgroup-v1.c | 1395 ++++++++++++++++++++++++++++ kernel/cgroup/cgroup.c | 1940 +++------------------------------------- kernel/cgroup/namespace.c | 155 +++ 7 files changed, 1907 insertions(+), 1802 deletions(-)
Quoted 9 lines · Tejun Heo
cgroup source files are getting a bit too unwieldy. Let's reorganize them.
* Move cgroup files in kernel to kernel/cgroup.
* Split
cgroup.cinto multiple files.The only functional change this patchset causes is loss of a
WARN_ON(); otherwise, everything remains identical.
Applied to cgroup/for-4.11.
Signature · 1 line
tejun