Commit 2e7ca206 authored by Linus Torvalds's avatar Linus Torvalds

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
parents ff2620f7 3c745417
...@@ -33,6 +33,9 @@ struct cgroup_taskset { ...@@ -33,6 +33,9 @@ struct cgroup_taskset {
struct list_head src_csets; struct list_head src_csets;
struct list_head dst_csets; struct list_head dst_csets;
/* the number of tasks in the set */
int nr_tasks;
/* the subsys currently being processed */ /* the subsys currently being processed */
int ssid; int ssid;
......
...@@ -2006,6 +2006,8 @@ static void cgroup_migrate_add_task(struct task_struct *task, ...@@ -2006,6 +2006,8 @@ static void cgroup_migrate_add_task(struct task_struct *task,
if (!cset->mg_src_cgrp) if (!cset->mg_src_cgrp)
return; return;
mgctx->tset.nr_tasks++;
list_move_tail(&task->cg_list, &cset->mg_tasks); list_move_tail(&task->cg_list, &cset->mg_tasks);
if (list_empty(&cset->mg_node)) if (list_empty(&cset->mg_node))
list_add_tail(&cset->mg_node, list_add_tail(&cset->mg_node,
...@@ -2094,11 +2096,8 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx) ...@@ -2094,11 +2096,8 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx)
struct css_set *cset, *tmp_cset; struct css_set *cset, *tmp_cset;
int ssid, failed_ssid, ret; int ssid, failed_ssid, ret;
/* methods shouldn't be called if no task is actually migrating */
if (list_empty(&tset->src_csets))
return 0;
/* check that we can legitimately attach to the cgroup */ /* check that we can legitimately attach to the cgroup */
if (tset->nr_tasks) {
do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
if (ss->can_attach) { if (ss->can_attach) {
tset->ssid = ssid; tset->ssid = ssid;
...@@ -2109,6 +2108,7 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx) ...@@ -2109,6 +2108,7 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx)
} }
} }
} while_each_subsys_mask(); } while_each_subsys_mask();
}
/* /*
* Now that we're guaranteed success, proceed to move all tasks to * Now that we're guaranteed success, proceed to move all tasks to
...@@ -2137,17 +2137,20 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx) ...@@ -2137,17 +2137,20 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx)
*/ */
tset->csets = &tset->dst_csets; tset->csets = &tset->dst_csets;
if (tset->nr_tasks) {
do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
if (ss->attach) { if (ss->attach) {
tset->ssid = ssid; tset->ssid = ssid;
ss->attach(tset); ss->attach(tset);
} }
} while_each_subsys_mask(); } while_each_subsys_mask();
}
ret = 0; ret = 0;
goto out_release_tset; goto out_release_tset;
out_cancel_attach: out_cancel_attach:
if (tset->nr_tasks) {
do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
if (ssid == failed_ssid) if (ssid == failed_ssid)
break; break;
...@@ -2156,6 +2159,7 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx) ...@@ -2156,6 +2159,7 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx)
ss->cancel_attach(tset); ss->cancel_attach(tset);
} }
} while_each_subsys_mask(); } while_each_subsys_mask();
}
out_release_tset: out_release_tset:
spin_lock_irq(&css_set_lock); spin_lock_irq(&css_set_lock);
list_splice_init(&tset->dst_csets, &tset->src_csets); 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,11 +3001,11 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
cgrp->subtree_control &= ~disable; cgrp->subtree_control &= ~disable;
ret = cgroup_apply_control(cgrp); ret = cgroup_apply_control(cgrp);
cgroup_finalize_control(cgrp, ret); cgroup_finalize_control(cgrp, ret);
if (ret)
goto out_unlock;
kernfs_activate(cgrp->kn); kernfs_activate(cgrp->kn);
ret = 0;
out_unlock: out_unlock:
cgroup_kn_unlock(of->kn); cgroup_kn_unlock(of->kn);
return ret ?: nbytes; return ret ?: nbytes;
...@@ -4669,6 +4673,10 @@ int __init cgroup_init(void) ...@@ -4669,6 +4673,10 @@ int __init cgroup_init(void)
if (ss->bind) if (ss->bind)
ss->bind(init_css_set.subsys[ssid]); ss->bind(init_css_set.subsys[ssid]);
mutex_lock(&cgroup_mutex);
css_populate_dir(init_css_set.subsys[ssid]);
mutex_unlock(&cgroup_mutex);
} }
/* init_css_set.subsys[] has been updated, re-hash */ /* init_css_set.subsys[] has been updated, re-hash */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment