aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/cgroup.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 15eb2273d80b..8c2835a9e192 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1902,10 +1902,6 @@ static void cgroup_migrate_add_src(struct css_set *src_cset,
1902 1902
1903 src_cgrp = cset_cgroup_from_root(src_cset, dst_cgrp->root); 1903 src_cgrp = cset_cgroup_from_root(src_cset, dst_cgrp->root);
1904 1904
1905 /* nothing to do if this cset already belongs to the cgroup */
1906 if (src_cgrp == dst_cgrp)
1907 return;
1908
1909 if (!list_empty(&src_cset->mg_preload_node)) 1905 if (!list_empty(&src_cset->mg_preload_node))
1910 return; 1906 return;
1911 1907
@@ -1920,13 +1916,14 @@ static void cgroup_migrate_add_src(struct css_set *src_cset,
1920 1916
1921/** 1917/**
1922 * cgroup_migrate_prepare_dst - prepare destination css_sets for migration 1918 * cgroup_migrate_prepare_dst - prepare destination css_sets for migration
1923 * @dst_cgrp: the destination cgroup 1919 * @dst_cgrp: the destination cgroup (may be %NULL)
1924 * @preloaded_csets: list of preloaded source css_sets 1920 * @preloaded_csets: list of preloaded source css_sets
1925 * 1921 *
1926 * Tasks are about to be moved to @dst_cgrp and all the source css_sets 1922 * Tasks are about to be moved to @dst_cgrp and all the source css_sets
1927 * have been preloaded to @preloaded_csets. This function looks up and 1923 * have been preloaded to @preloaded_csets. This function looks up and
1928 * pins all destination css_sets, links each to its source, and put them on 1924 * pins all destination css_sets, links each to its source, and append them
1929 * @preloaded_csets. 1925 * to @preloaded_csets. If @dst_cgrp is %NULL, the destination of each
1926 * source css_set is assumed to be its cgroup on the default hierarchy.
1930 * 1927 *
1931 * This function must be called after cgroup_migrate_add_src() has been 1928 * This function must be called after cgroup_migrate_add_src() has been
1932 * called on each migration source css_set. After migration is performed 1929 * called on each migration source css_set. After migration is performed
@@ -1937,19 +1934,34 @@ static int cgroup_migrate_prepare_dst(struct cgroup *dst_cgrp,
1937 struct list_head *preloaded_csets) 1934 struct list_head *preloaded_csets)
1938{ 1935{
1939 LIST_HEAD(csets); 1936 LIST_HEAD(csets);
1940 struct css_set *src_cset; 1937 struct css_set *src_cset, *tmp_cset;
1941 1938
1942 lockdep_assert_held(&cgroup_mutex); 1939 lockdep_assert_held(&cgroup_mutex);
1943 1940
1944 /* look up the dst cset for each src cset and link it to src */ 1941 /* look up the dst cset for each src cset and link it to src */
1945 list_for_each_entry(src_cset, preloaded_csets, mg_preload_node) { 1942 list_for_each_entry_safe(src_cset, tmp_cset, preloaded_csets, mg_preload_node) {
1946 struct css_set *dst_cset; 1943 struct css_set *dst_cset;
1947 1944
1948 dst_cset = find_css_set(src_cset, dst_cgrp); 1945 dst_cset = find_css_set(src_cset,
1946 dst_cgrp ?: src_cset->dfl_cgrp);
1949 if (!dst_cset) 1947 if (!dst_cset)
1950 goto err; 1948 goto err;
1951 1949
1952 WARN_ON_ONCE(src_cset->mg_dst_cset || dst_cset->mg_dst_cset); 1950 WARN_ON_ONCE(src_cset->mg_dst_cset || dst_cset->mg_dst_cset);
1951
1952 /*
1953 * If src cset equals dst, it's noop. Drop the src.
1954 * cgroup_migrate() will skip the cset too. Note that we
1955 * can't handle src == dst as some nodes are used by both.
1956 */
1957 if (src_cset == dst_cset) {
1958 src_cset->mg_src_cgrp = NULL;
1959 list_del_init(&src_cset->mg_preload_node);
1960 put_css_set(src_cset, false);
1961 put_css_set(dst_cset, false);
1962 continue;
1963 }
1964
1953 src_cset->mg_dst_cset = dst_cset; 1965 src_cset->mg_dst_cset = dst_cset;
1954 1966
1955 if (list_empty(&dst_cset->mg_preload_node)) 1967 if (list_empty(&dst_cset->mg_preload_node))
@@ -1958,7 +1970,7 @@ static int cgroup_migrate_prepare_dst(struct cgroup *dst_cgrp,
1958 put_css_set(dst_cset, false); 1970 put_css_set(dst_cset, false);
1959 } 1971 }
1960 1972
1961 list_splice(&csets, preloaded_csets); 1973 list_splice_tail(&csets, preloaded_csets);
1962 return 0; 1974 return 0;
1963err: 1975err:
1964 cgroup_migrate_finish(&csets); 1976 cgroup_migrate_finish(&csets);