diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h index 2e44dc8634dc..1ba94ffaff9d 100644 --- a/kernel/cgroup/cpuset-internal.h +++ b/kernel/cgroup/cpuset-internal.h @@ -161,6 +161,11 @@ struct cpuset { */ bool remote_partition; + /* + * Set to true when a remote partition is undergoing update. + */ + bool remote_partition_updating; + /* * number of SCHED_DEADLINE tasks attached to this cpuset, so that we * know when to rebuild associated root domain bandwidth information. diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 585abff94e8c..f674a0c9baf7 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -1775,6 +1775,7 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *xcpus, goto invalidate; } + cs->remote_partition_updating = true; spin_lock_irq(&callback_lock); if (adding) partition_xcpus_add(prs, NULL, tmp->addmask); @@ -1796,6 +1797,7 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *xcpus, */ cpuset_update_tasks_cpumask(&top_cpuset, tmp->new_cpus); update_sibling_cpumasks(&top_cpuset, NULL, tmp); + cs->remote_partition_updating = false; return; invalidate: @@ -2237,16 +2239,19 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp, old_prs = new_prs = cp->partition_root_state; /* - * For child remote partition root (!= cs), we need to call - * remote_cpus_update() if effective_xcpus will be changed. - * Otherwise, we can skip the whole subtree. + * For a child remote partition with remote_partition_updating + * set, we can skip the whole subtree as the this function will + * be called eventually. We can also skip the subtree if the + * effective_xcpus isn't going to be changed. Otherwise, we + * will have to call remote_cpus_update(). * * remote_cpus_update() will reuse tmp->new_cpus only after * its value is being processed. */ if (remote && (cp != cs)) { compute_excpus(cp, tmp->new_cpus); - if (cpumask_equal(cp->effective_xcpus, tmp->new_cpus)) { + if (cp->remote_partition_updating || + cpumask_equal(cp->effective_xcpus, tmp->new_cpus)) { pos_css = css_rightmost_descendant(pos_css); continue; } diff --git a/tools/testing/selftests/cgroup/test_cpuset_prs.sh b/tools/testing/selftests/cgroup/test_cpuset_prs.sh index f09a0a78ead2..ea8e1ff3014c 100755 --- a/tools/testing/selftests/cgroup/test_cpuset_prs.sh +++ b/tools/testing/selftests/cgroup/test_cpuset_prs.sh @@ -347,6 +347,7 @@ TEST_MATRIX=( " C0-3 C1-3 C2-3 C4 X2-3 X2-3 X2-3:P2 P2:C4-5 0 A3:2-3|B1:4-5 A3:P2|B1:P2 2-5" " C4:X0-3 X1-3 X2-3 . . P2 . . 0 A1:4|A2:1-3|A3:1-3 A2:P2 1-3" " C4:X0-3 X1-3 X2-3 . . . P2 . 0 A1:4|A2:4|A3:2-3 A3:P2 2-3" + " CX1-6 C1-4:P1 . C4-5 . C1-3 . . 0 A1:4-6|A2:1-3|B1:4-5 A2:P1" # Nested remote/local partition tests " C0-3 C1-3 C2-3 C4-5 X2-3 X2-3:P1 P2 P1 0 A1:0-1|A2:|A3:2-3|B1:4-5 \