Skip to content

Commit f817de9

Browse files
committed
cgroup: prepare migration path for unified hierarchy
Unified hierarchy implementation would require re-migrating tasks onto the same cgroup on the default hierarchy to reflect updated effective csses. Update cgroup_migrate_prepare_dst() so that it accepts NULL as the destination cgrp. When NULL is specified, the destination is considered to be the cgroup on the default hierarchy associated with each css_set. After this change, the identity check in cgroup_migrate_add_src() isn't sufficient for noop detection as the associated csses may change without any cgroup association changing. The only way to tell whether a migration is noop or not is testing whether the source and destination csets are identical. The noop check in cgroup_migrate_add_src() is removed and cset identity test is added to cgroup_migreate_prepare_dst(). If it's detected that source and destination csets are identical, the cset is removed removed from @preloaded_csets and all the migration nodes are cleared which makes cgroup_migrate() ignore the cset. Also, make the function append the destination css_sets to @preloaded_list so that destination css_sets always come after source css_sets. Signed-off-by: Tejun Heo <[email protected]> Acked-by: Li Zefan <[email protected]>
1 parent 7fd8c56 commit f817de9

File tree

1 file changed

+23
-11
lines changed

1 file changed

+23
-11
lines changed

kernel/cgroup.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,10 +1902,6 @@ static void cgroup_migrate_add_src(struct css_set *src_cset,
19021902

19031903
src_cgrp = cset_cgroup_from_root(src_cset, dst_cgrp->root);
19041904

1905-
/* nothing to do if this cset already belongs to the cgroup */
1906-
if (src_cgrp == dst_cgrp)
1907-
return;
1908-
19091905
if (!list_empty(&src_cset->mg_preload_node))
19101906
return;
19111907

@@ -1920,13 +1916,14 @@ static void cgroup_migrate_add_src(struct css_set *src_cset,
19201916

19211917
/**
19221918
* 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)
19241920
* @preloaded_csets: list of preloaded source css_sets
19251921
*
19261922
* Tasks are about to be moved to @dst_cgrp and all the source css_sets
19271923
* 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
1929-
* @preloaded_csets.
1924+
* pins all destination css_sets, links each to its source, and append them
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.
19301927
*
19311928
* This function must be called after cgroup_migrate_add_src() has been
19321929
* 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,
19371934
struct list_head *preloaded_csets)
19381935
{
19391936
LIST_HEAD(csets);
1940-
struct css_set *src_cset;
1937+
struct css_set *src_cset, *tmp_cset;
19411938

19421939
lockdep_assert_held(&cgroup_mutex);
19431940

19441941
/* 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) {
19461943
struct css_set *dst_cset;
19471944

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);
19491947
if (!dst_cset)
19501948
goto err;
19511949

19521950
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+
19531965
src_cset->mg_dst_cset = dst_cset;
19541966

19551967
if (list_empty(&dst_cset->mg_preload_node))
@@ -1958,7 +1970,7 @@ static int cgroup_migrate_prepare_dst(struct cgroup *dst_cgrp,
19581970
put_css_set(dst_cset, false);
19591971
}
19601972

1961-
list_splice(&csets, preloaded_csets);
1973+
list_splice_tail(&csets, preloaded_csets);
19621974
return 0;
19631975
err:
19641976
cgroup_migrate_finish(&csets);

0 commit comments

Comments
 (0)