|
@@ -2006,6 +2006,8 @@ static void cgroup_migrate_add_task(struct task_struct *task,
|
|
|
if (!cset->mg_src_cgrp)
|
|
|
return;
|
|
|
|
|
|
+ mgctx->tset.nr_tasks++;
|
|
|
+
|
|
|
list_move_tail(&task->cg_list, &cset->mg_tasks);
|
|
|
if (list_empty(&cset->mg_node))
|
|
|
list_add_tail(&cset->mg_node,
|
|
@@ -2094,21 +2096,19 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx)
|
|
|
struct css_set *cset, *tmp_cset;
|
|
|
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 */
|
|
|
- do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
|
|
|
- if (ss->can_attach) {
|
|
|
- tset->ssid = ssid;
|
|
|
- ret = ss->can_attach(tset);
|
|
|
- if (ret) {
|
|
|
- failed_ssid = ssid;
|
|
|
- goto out_cancel_attach;
|
|
|
+ if (tset->nr_tasks) {
|
|
|
+ do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
|
|
|
+ if (ss->can_attach) {
|
|
|
+ tset->ssid = ssid;
|
|
|
+ ret = ss->can_attach(tset);
|
|
|
+ if (ret) {
|
|
|
+ failed_ssid = ssid;
|
|
|
+ goto out_cancel_attach;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- } while_each_subsys_mask();
|
|
|
+ } while_each_subsys_mask();
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* 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)
|
|
|
*/
|
|
|
tset->csets = &tset->dst_csets;
|
|
|
|
|
|
- do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
|
|
|
- if (ss->attach) {
|
|
|
- tset->ssid = ssid;
|
|
|
- ss->attach(tset);
|
|
|
- }
|
|
|
- } while_each_subsys_mask();
|
|
|
+ if (tset->nr_tasks) {
|
|
|
+ do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
|
|
|
+ if (ss->attach) {
|
|
|
+ tset->ssid = ssid;
|
|
|
+ ss->attach(tset);
|
|
|
+ }
|
|
|
+ } while_each_subsys_mask();
|
|
|
+ }
|
|
|
|
|
|
ret = 0;
|
|
|
goto out_release_tset;
|
|
|
|
|
|
out_cancel_attach:
|
|
|
- do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
|
|
|
- if (ssid == failed_ssid)
|
|
|
- break;
|
|
|
- if (ss->cancel_attach) {
|
|
|
- tset->ssid = ssid;
|
|
|
- ss->cancel_attach(tset);
|
|
|
- }
|
|
|
- } while_each_subsys_mask();
|
|
|
+ if (tset->nr_tasks) {
|
|
|
+ do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
|
|
|
+ if (ssid == failed_ssid)
|
|
|
+ break;
|
|
|
+ if (ss->cancel_attach) {
|
|
|
+ tset->ssid = ssid;
|
|
|
+ ss->cancel_attach(tset);
|
|
|
+ }
|
|
|
+ } while_each_subsys_mask();
|
|
|
+ }
|
|
|
out_release_tset:
|
|
|
spin_lock_irq(&css_set_lock);
|
|
|
list_splice_init(&tset->dst_csets, &tset->src_csets);
|