From: Waiman Long <longman@redhat.com> mainline inclusion from mainline-v6.15 commit 8bf450f3aec3d1bbd725d179502c64b8992588e4 category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9899 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- When remote_partition_disable() is called to disable a remote partition, it always sets the partition to an invalid partition state. It should only do so if an error code (prs_err) has been set. Correct that and add proper error code in places where remote_partition_disable() is called due to error. Fixes: 181c8e091aae ("cgroup/cpuset: Introduce remote partition") Signed-off-by: Waiman Long <longman@redhat.com> Signed-off-by: Tejun Heo <tj@kernel.org> Conflicts: kernel/cgroup/cpuset.c [ partition_xcpus_del()/update_unbound_workqueue_cpumask() usage is dropped; the direct subpartitions_cpus/top_cpuset cpumask operations are kept (isolated_cpus tracking not in OLK-6.6). PERR_ACCESS is provided by the backport of e55f45b4bafe earlier in this series. ] Signed-off-by: Zhang Qiao <zhangqiao22@huawei.com> --- kernel/cgroup/cpuset.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 38001101981b..7e572283100b 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -1729,6 +1729,7 @@ static int remote_partition_enable(struct cpuset *cs, struct tmpmasks *tmp) } list_add(&cs->remote_sibling, &remote_children); spin_unlock_irq(&callback_lock); + cs->prs_err = 0; /* * Proprogate changes in top_cpuset's effective_cpus down the hierarchy. @@ -1762,9 +1763,10 @@ static void remote_partition_disable(struct cpuset *cs, struct tmpmasks *tmp) cpumask_or(top_cpuset.effective_cpus, top_cpuset.effective_cpus, tmp->new_cpus); list_del_init(&cs->remote_sibling); - cs->partition_root_state = -cs->partition_root_state; - if (!cs->prs_err) - cs->prs_err = PERR_INVCPUS; + if (cs->prs_err) + cs->partition_root_state = -cs->partition_root_state; + else + cs->partition_root_state = PRS_MEMBER; reset_partition_data(cs); spin_unlock_irq(&callback_lock); @@ -1794,8 +1796,10 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *newmask, WARN_ON_ONCE(!cpumask_subset(cs->effective_xcpus, subpartitions_cpus)); - if (cpumask_empty(newmask)) + if (cpumask_empty(newmask)) { + cs->prs_err = PERR_CPUSEMPTY; goto invalidate; + } adding = cpumask_andnot(tmp->addmask, newmask, cs->effective_xcpus); deleting = cpumask_andnot(tmp->delmask, cs->effective_xcpus, newmask); @@ -1805,10 +1809,15 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *newmask, * not allocated to other partitions and there are effective_cpus * left in the top cpuset. */ - if (adding && (!capable(CAP_SYS_ADMIN) || - cpumask_intersects(tmp->addmask, subpartitions_cpus) || - cpumask_subset(top_cpuset.effective_cpus, tmp->addmask))) - goto invalidate; + if (adding) { + if (!capable(CAP_SYS_ADMIN)) + cs->prs_err = PERR_ACCESS; + else if (cpumask_intersects(tmp->addmask, subpartitions_cpus) || + cpumask_subset(top_cpuset.effective_cpus, tmp->addmask)) + cs->prs_err = PERR_NOCPUS; + if (cs->prs_err) + goto invalidate; + } spin_lock_irq(&callback_lock); if (adding) { @@ -1933,7 +1942,7 @@ static bool prstate_housekeeping_conflict(int prstate, struct cpumask *new_cpus) * The partcmd_update command is used by update_cpumasks_hier() with newmask * NULL and update_cpumask() with newmask set. The partcmd_invalidate is used * by update_cpumask() with NULL newmask. In both cases, the callers won't - * check for error and so partition_root_state and prs_error will be updated + * check for error and so partition_root_state and prs_err will be updated * directly. */ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd, @@ -4652,6 +4661,7 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp) if (remote && cpumask_empty(&new_cpus) && partition_is_populated(cs, NULL)) { + cs->prs_err = PERR_HOTPLUG; remote_partition_disable(cs, tmp); compute_effective_cpumask(&new_cpus, cs, parent); remote = false; -- 2.18.0