Re: [PATCH-next 2/6] cgroup/cpuset: Properly compute effective xcpus in update_parent_effective_cpumask()

From: Guopeng Zhang

Date: Mon Oct 26 2026 - 01:47:07 EST




在 2026/10/24 04:45, Waiman Long 写道:
> On 10/22/26 9:53 PM, Guopeng Zhang wrote:
>>
>> 在 2026/10/22 23:00, Waiman Long 写道:
>>> On 10/22/26 9:45 AM, Guopeng Zhang wrote:
>>>> Hi Longman,
>>>>
>>>> 在 2026/10/22 11:16, Waiman Long 写道:
>>>>> Since the introduction of cpuset.cpus.exclusive in commit
>>>>> e2ffe502ba45 ("cgroup/cpuset: Add cpuset.cpus.exclusive for v2"), a
>>>>> compute_effective_exclusive_cpumask() helper which is later renamed to
>>>>> compute_excpus() is added to compute the effective xcpus of a partition
>>>>> root. However update_parent_effective_cpumask() is not updated in all
>>>>> proper places to use the new helper to check if a given cpuset should
>>>>> remain a valid partition root. This can cause a cpuset to incorrectly
>>>>> remain a valid partition root even if no effective xcpus is left.
>>>>>
>>>>> Fix that problem by using compute_excpus() to compute the effective xcpus
>>>>> into delmask in all cases except partcmd_disable and partcmd_invalidate
>>>>> and use it for tasks_nocpu_error() check as well as checking its
>>>>> emptiness. This enables us to catch invalid partition root more
>>>>> accurately in update_parent_effective_cpumask().
>>>>>
>>>> I re-tested the repro from the link below on top of this series
>>>> (applied on cgroup/for-7.4-fixes), and it still fails:
>>>>
>>>>     https://lore.kernel.org/all/20261010075947.333549-3-guopeng.zhang@xxxxxxxxx/
>>>>
>>>>     cd /sys/fs/cgroup
>>>>     echo +cpuset > cgroup.subtree_control
>>>>     mkdir A
>>>>     echo 0-7 > A/cpuset.cpus
>>>>     echo 0-7 > A/cpuset.cpus.exclusive
>>>>     echo root > A/cpuset.cpus.partition
>>>>     cat A/cpuset.cpus.partition
>>>>     echo 1 > A/cpuset.cpus.exclusive
>>>>     cat A/cpuset.cpus.partition
>>>>
>>>> The last command still shows "root invalid (Parent unable to distribute
>>>> cpu downstream)".
>>>>
>>>> In this case compute_excpus() returns the stale user mask unchanged.
>>>> user_xcpus() is gone from update_parent_effective_cpumask(), but the
>>>> dependency just moved one level down: the new code calls
>>>> compute_excpus(cs, tmp->delmask), and its first line is
>>>>
>>>>     cpumask_and(excpus, user_xcpus(cs), parent->effective_xcpus)
>>>>
>>>> Here user_xcpus(cs) is cs->exclusive_cpus, which still holds the old
>>>> 0-7 when compute_excpus() runs: update_exclusive_cpumask() publishes
>>>> cs->exclusive_cpus only after partition_cpus_change(). Nothing corrects
>>>> it either - the sibling trim is skipped as exclusive_cpus is non-empty,
>>>> and for a direct child of the root cpuset the intersection with
>>>> parent->effective_xcpus is a no-op. So the stale 0-7 mask still reaches
>>>> tasks_nocpu_error() and PERR_NOCPUS is set again. Please point it out
>>>> if I got the analysis wrong.
>>>>
>>>> I have rebased my fix on top of this series and the partition recovers
>>>> correctly with it applied. Should the fix be folded into this patch,
>>>> or is there a better way to fix it? Happy to hear your thoughts.
>>> You are right. My patch series won't fix this particular issue. However, converting an invalid partition back to a valid one is done on a best effort basis. There is no guarantee that it will always happen. Just echo "root" to "cpuset.cpus.partition" again will make it valid again. So it is not a real bug from my point of view. It is just a nice to have feature.
>>>
>> Thanks for the explanation. This helps me better understand the
>> intended behavior of partition recovery.
>
> I did find the reason why your test case isn't working. I have made some adjustment in patch 2 which should make your test case work now with the v2 series.
>

Thanks for looking into this issue again.

Cheers,
Guopeng