Re: [PATCH 1/2] xen/sched: core: skip missing vcpu slots in sched_move_domain()

Juergen Gross <[email protected]>
Newsgroups org.xenproject.lists.xen-devel
Message-ID <[email protected]>
On 18.08.26 12:35, Andrew Cooper wrote:
> On 18/08/2026 11:13 am, Jürgen Groß wrote:
>> On 18.08.26 12:04, Andrew Cooper wrote:
>>> On 18/08/2026 8:53 am, Furkan Çalışkan wrote:
>>>> On 8/18/26 10:11, Jürgen Groß wrote:
>>>>> On 18.08.26 08:32, Furkan Caliskan wrote:
>>>>>> sched_move_domain() derives the number of units to rebuild from
>>>>>> d->max_vcpus, which is fixed at domain creation and never rolled
>>>>>> back if vcpu_create() fails partway through building a domain. So
>>>>>> d->vcpu[i] can be NULL for some i even though max_vcpus still
>>>>>> counts it - this happens if sched_alloc_udata() returns NULL.
>>>>>>
>>>>>> The per-unit loop doesn't check for this: it sets
>>>>>> unit->vcpu_list = d->vcpu[unit_id] (NULL) and hands that broken
>>>>>> unit straight to the destination scheduler's alloc_udata(),
>>>>>> which assumes vcpu_list is always valid and crashes Xen when
>>>>>> it is not.
>>>>>>
>>>>>> Reproduced by building a domain in a non-default cpupool where
>>>>>> vcpu creation fails partway through, then destroying it.
>>>>>> domain_kill() moves the domain back to the default cpupool via
>>>>>> sched_move_domain() before actually destroying it, crashing
>>>>>> inside the destination scheduler's alloc_udata() (seen in
>>>>>> Credit2's csched2_alloc_udata() -> is_idle_unit() -> NULL deref).
>>>>>>
>>>>>> Before building a unit in sched_move_domain(), check that all of
>>>>>> its vcpu slots are populated, and skip it if any are missing. The
>>>>>> rest of the function walks the vcpus that actually exist, via
>>>>>> for_each_vcpu() rather than n_units, so skipping a unit here
>>>>>> does not leave anything else out of sync.
>>>>>>
>>>>>> Signed-off-by: Furkan Caliskan <[email protected]>
>>>>>> ---
>>>>>>     xen/common/sched/core.c | 19 +++++++++++++++++++
>>>>>>     1 file changed, 19 insertions(+)
>>>>>>
>>>>>> diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
>>>>>> index d3a0a97e1d..d542c76543 100644
>>>>>> --- a/xen/common/sched/core.c
>>>>>> +++ b/xen/common/sched/core.c
>>>>>> @@ -745,6 +745,25 @@ int sched_move_domain(struct domain *d,
>>>>>> struct cpupool *c)
>>>>>>           for ( unit_idx = 0; unit_idx < n_units; unit_idx++ )
>>>>>>         {
>>>>>> +        /*
>>>>>> +         * Skip this unit if any of its vcpus is missing. Bounded by
>>>>>> +         * max_vcpus.
>>>>>> +         */
>>>>>> +        bool vcpu_failed = false;
>>>>>> +
>>>>>> +        for ( unsigned int i = 0;
>>>>>> +              i < gran && unit_idx * gran + i < d->max_vcpus; i++ )
>>>>>> +        {
>>>>>> +            if ( !d->vcpu[unit_idx * gran + i] )
>>>>>> +            {
>>>>>> +                vcpu_failed = true;
>>>>>> +                break;
>>>>>> +            }
>>>>>> +        }
>>>>>> +
>>>>>> +        if ( vcpu_failed )
>>>>>> +            continue;
>>>>> I don't think this is correct.
>>>>>
>>>>> If there are some vcpus in the unit you will loose them (i.e. make
>>>>> them no
>>>>> longer be able to be scheduled), right?
>>>>>
>>>>> For a dying domain this might be okay, but not for one still
>>>>> active. So I think
>>>>> you should at least verify the domain is dying, otherwise
>>>>> sched_move_domain()
>>>>> should just fail.
>>>>>
>>>>> An alternative might be to fix the NULL dereferencing where needed,
>>>>> but this
>>>>> could become tedious.
>>>>>
>>>>>
>>>>> Juergen
>>>> Right. My initial attempt only checked 'd->vcpu[unit_idx*gran]'
>>>> for the head vCPU. The crash happens when unit->vcpu_list is set
>>>> to d->vcpu[unit_idx*gran] (which is NULL) and passed to
>>>> 'alloc_udata()',
>>>> causing a NULL dereference.
>>>>
>>>> I expanded the loop over 'gran' to handle core-scheduling cases where a
>>>> subsequent vCPU fails mid-unit, but as you pointed out, that drops the
>>>> whole unit for active domain.
>>>>
>>>> I'll update the patch to check d->is_dying to skip incomplete units
>>>> only for dying domains, and have sched_move_domain() fail if an active
>>>> domain has missing vCPUs
>>>
>>> I'm afraid that wont fix everything.
>>
>> Why not?
> 
> domU's in this situation do not have is_dying set.

Please clarify what you mean with "this situation".

sched_move_domain() is being called either due to an admin action
("xl cpupool-migrate"), or during domain_kill() in order to move the
domain to cpupool0 for avoiding a zombie domain blocking cpupool
removal.

The first case is allowed to fail, which the suggested fix would do,
while the second case is happening only after DOMDYING_dying has been
set for the domain.


Juergen
OpenPGP_0xB0DE9DD628BF132F.asc (application/pgp-keys, 3.6 KB)
-----BEGIN PGP PUBLIC KEY BLOCK-----

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
kt+z4drzFUyEjLM1vVvIMjkUoJs=
=eeAB
-----END PGP PUBLIC KEY BLOCK-----
OpenPGP_signature.asc (application/pgp-signature, 495 B)
-----BEGIN PGP SIGNATURE-----

wsB5BAABCAAjFiEEhRJncuj2BJSl0Jf3sN6d1ii/Ey8FAmqEOEUFAwAAAAAACgkQsN6d1ii/Ey/5
2QgAir7+RRdj7Ppt76PZ+PY/ynyBAS2m+1QjvErVZlp6atv8ZcyUy6irqmaf16M/YDLxM7/t+QFc
lDIiqZKDoH1CWOgp7QDg8ZsP45Zj/4MyRaScucfCGzLH9bOqX+UPzPe31f8LmFCXKOyHE16m7kGt
WfNnJAwMsEvmr6GPAPJrpdN223F7wL7T1XHL9iGG5Df56YXxh4L7wQk1XmlFRAOWdBJZIsZzwoFr
6cs9wTSs1Zivt+upHUxACS5YFCREcdUP5S0Y+UmivObcwD/B18nZwNULBOxTfXHs5CZ8NcJcSRZu
SqlrmWuvo7Dn5B9Gq/bKyEEy66UfvpA58k6HPpt5GA==
=poQi
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.