diff options
-rw-r--r-- | kernel/cgroup.c | 34 |
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; |
1963 | err: | 1975 | err: |
1964 | cgroup_migrate_finish(&csets); | 1976 | cgroup_migrate_finish(&csets); |