diff options
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index f783af900208..306ad0ed19ef 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -2810,10 +2810,28 @@ void css_task_iter_end(struct css_task_iter *it) | |||
2810 | */ | 2810 | */ |
2811 | int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) | 2811 | int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) |
2812 | { | 2812 | { |
2813 | LIST_HEAD(preloaded_csets); | ||
2814 | struct cgrp_cset_link *link; | ||
2813 | struct css_task_iter it; | 2815 | struct css_task_iter it; |
2814 | struct task_struct *task; | 2816 | struct task_struct *task; |
2815 | int ret = 0; | 2817 | int ret; |
2818 | |||
2819 | mutex_lock(&cgroup_mutex); | ||
2820 | |||
2821 | /* all tasks in @from are being moved, all csets are source */ | ||
2822 | down_read(&css_set_rwsem); | ||
2823 | list_for_each_entry(link, &from->cset_links, cset_link) | ||
2824 | cgroup_migrate_add_src(link->cset, to, &preloaded_csets); | ||
2825 | up_read(&css_set_rwsem); | ||
2816 | 2826 | ||
2827 | ret = cgroup_migrate_prepare_dst(to, &preloaded_csets); | ||
2828 | if (ret) | ||
2829 | goto out_err; | ||
2830 | |||
2831 | /* | ||
2832 | * Migrate tasks one-by-one until @form is empty. This fails iff | ||
2833 | * ->can_attach() fails. | ||
2834 | */ | ||
2817 | do { | 2835 | do { |
2818 | css_task_iter_start(&from->dummy_css, &it); | 2836 | css_task_iter_start(&from->dummy_css, &it); |
2819 | task = css_task_iter_next(&it); | 2837 | task = css_task_iter_next(&it); |
@@ -2822,13 +2840,13 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) | |||
2822 | css_task_iter_end(&it); | 2840 | css_task_iter_end(&it); |
2823 | 2841 | ||
2824 | if (task) { | 2842 | if (task) { |
2825 | mutex_lock(&cgroup_mutex); | 2843 | ret = cgroup_migrate(to, task, false); |
2826 | ret = cgroup_attach_task(to, task, false); | ||
2827 | mutex_unlock(&cgroup_mutex); | ||
2828 | put_task_struct(task); | 2844 | put_task_struct(task); |
2829 | } | 2845 | } |
2830 | } while (task && !ret); | 2846 | } while (task && !ret); |
2831 | 2847 | out_err: | |
2848 | cgroup_migrate_finish(&preloaded_csets); | ||
2849 | mutex_unlock(&cgroup_mutex); | ||
2832 | return ret; | 2850 | return ret; |
2833 | } | 2851 | } |
2834 | 2852 | ||