summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-31 17:03:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-31 17:03:05 -0400
commit2e7ca2064cbb070834233ea540ac9c2ff0d09894 (patch)
tree7ab24df1442f70644b268af279121980f4c03c75 /kernel
parentff2620f778b1942eea40bd43773094dbc0e76c7e (diff)
parent3c74541777302eec43a0d1327c4d58b8659a776b (diff)
Merge branch 'for-4.13-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup fixes from Tejun Heo: "Several cgroup bug fixes. - cgroup core was calling a migration callback on empty migrations, which could make cpuset crash. - There was a very subtle bug where the controller interface files aren't created directly when cgroup2 is mounted. Because later operations create them, this bug didn't get noticed earlier. - Failed writes to cgroup.subtree_control were incorrectly returning zero" * 'for-4.13-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: cgroup: fix error return value from cgroup_subtree_control() cgroup: create dfl_root files on subsys registration cgroup: don't call migration methods if there are no tasks to migrate
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cgroup/cgroup-internal.h3
-rw-r--r--kernel/cgroup/cgroup.c66
2 files changed, 40 insertions, 29 deletions
diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h
index 793565c05742..8b4c3c2f2509 100644
--- a/kernel/cgroup/cgroup-internal.h
+++ b/kernel/cgroup/cgroup-internal.h
@@ -33,6 +33,9 @@ struct cgroup_taskset {
33 struct list_head src_csets; 33 struct list_head src_csets;
34 struct list_head dst_csets; 34 struct list_head dst_csets;
35 35
36 /* the number of tasks in the set */
37 int nr_tasks;
38
36 /* the subsys currently being processed */ 39 /* the subsys currently being processed */
37 int ssid; 40 int ssid;
38 41
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 620794a20a33..df2e0f14a95d 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -2006,6 +2006,8 @@ static void cgroup_migrate_add_task(struct task_struct *task,
2006 if (!cset->mg_src_cgrp) 2006 if (!cset->mg_src_cgrp)
2007 return; 2007 return;
2008 2008
2009 mgctx->tset.nr_tasks++;
2010
2009 list_move_tail(&task->cg_list, &cset->mg_tasks); 2011 list_move_tail(&task->cg_list, &cset->mg_tasks);
2010 if (list_empty(&cset->mg_node)) 2012 if (list_empty(&cset->mg_node))
2011 list_add_tail(&cset->mg_node, 2013 list_add_tail(&cset->mg_node,
@@ -2094,21 +2096,19 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx)
2094 struct css_set *cset, *tmp_cset; 2096 struct css_set *cset, *tmp_cset;
2095 int ssid, failed_ssid, ret; 2097 int ssid, failed_ssid, ret;
2096 2098
2097 /* methods shouldn't be called if no task is actually migrating */
2098 if (list_empty(&tset->src_csets))
2099 return 0;
2100
2101 /* check that we can legitimately attach to the cgroup */ 2099 /* check that we can legitimately attach to the cgroup */
2102 do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { 2100 if (tset->nr_tasks) {
2103 if (ss->can_attach) { 2101 do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
2104 tset->ssid = ssid; 2102 if (ss->can_attach) {
2105 ret = ss->can_attach(tset); 2103 tset->ssid = ssid;
2106 if (ret) { 2104 ret = ss->can_attach(tset);
2107 failed_ssid = ssid; 2105 if (ret) {
2108 goto out_cancel_attach; 2106 failed_ssid = ssid;
2107 goto out_cancel_attach;
2108 }
2109 } 2109 }
2110 } 2110 } while_each_subsys_mask();
2111 } while_each_subsys_mask(); 2111 }
2112 2112
2113 /* 2113 /*
2114 * Now that we're guaranteed success, proceed to move all tasks to 2114 * Now that we're guaranteed success, proceed to move all tasks to
@@ -2137,25 +2137,29 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx)
2137 */ 2137 */
2138 tset->csets = &tset->dst_csets; 2138 tset->csets = &tset->dst_csets;
2139 2139
2140 do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { 2140 if (tset->nr_tasks) {
2141 if (ss->attach) { 2141 do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
2142 tset->ssid = ssid; 2142 if (ss->attach) {
2143 ss->attach(tset); 2143 tset->ssid = ssid;
2144 } 2144 ss->attach(tset);
2145 } while_each_subsys_mask(); 2145 }
2146 } while_each_subsys_mask();
2147 }
2146 2148
2147 ret = 0; 2149 ret = 0;
2148 goto out_release_tset; 2150 goto out_release_tset;
2149 2151
2150out_cancel_attach: 2152out_cancel_attach:
2151 do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { 2153 if (tset->nr_tasks) {
2152 if (ssid == failed_ssid) 2154 do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
2153 break; 2155 if (ssid == failed_ssid)
2154 if (ss->cancel_attach) { 2156 break;
2155 tset->ssid = ssid; 2157 if (ss->cancel_attach) {
2156 ss->cancel_attach(tset); 2158 tset->ssid = ssid;
2157 } 2159 ss->cancel_attach(tset);
2158 } while_each_subsys_mask(); 2160 }
2161 } while_each_subsys_mask();
2162 }
2159out_release_tset: 2163out_release_tset:
2160 spin_lock_irq(&css_set_lock); 2164 spin_lock_irq(&css_set_lock);
2161 list_splice_init(&tset->dst_csets, &tset->src_csets); 2165 list_splice_init(&tset->dst_csets, &tset->src_csets);
@@ -2997,11 +3001,11 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
2997 cgrp->subtree_control &= ~disable; 3001 cgrp->subtree_control &= ~disable;
2998 3002
2999 ret = cgroup_apply_control(cgrp); 3003 ret = cgroup_apply_control(cgrp);
3000
3001 cgroup_finalize_control(cgrp, ret); 3004 cgroup_finalize_control(cgrp, ret);
3005 if (ret)
3006 goto out_unlock;
3002 3007
3003 kernfs_activate(cgrp->kn); 3008 kernfs_activate(cgrp->kn);
3004 ret = 0;
3005out_unlock: 3009out_unlock:
3006 cgroup_kn_unlock(of->kn); 3010 cgroup_kn_unlock(of->kn);
3007 return ret ?: nbytes; 3011 return ret ?: nbytes;
@@ -4669,6 +4673,10 @@ int __init cgroup_init(void)
4669 4673
4670 if (ss->bind) 4674 if (ss->bind)
4671 ss->bind(init_css_set.subsys[ssid]); 4675 ss->bind(init_css_set.subsys[ssid]);
4676
4677 mutex_lock(&cgroup_mutex);
4678 css_populate_dir(init_css_set.subsys[ssid]);
4679 mutex_unlock(&cgroup_mutex);
4672 } 4680 }
4673 4681
4674 /* init_css_set.subsys[] has been updated, re-hash */ 4682 /* init_css_set.subsys[] has been updated, re-hash */