[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 1/2] xen/sched: core: skip missing vcpu slots in sched_move_domain()
- To: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Furkan Çalışkan <frn1furkan10@xxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
- From: Jürgen Groß <jgross@xxxxxxxx>
- Date: Tue, 18 Aug 2026 12:13:42 +0200
- Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=google header.d=suse.com header.i="@suse.com" header.h="Content-Type:In-Reply-To:Autocrypt:From:Content-Language:References:Cc:To:Subject:User-Agent:MIME-Version:Date:Message-ID"
- Autocrypt: addr=jgross@xxxxxxxx; keydata= xsBNBFOMcBYBCACgGjqjoGvbEouQZw/ToiBg9W98AlM2QHV+iNHsEs7kxWhKMjrioyspZKOB ycWxw3ie3j9uvg9EOB3aN4xiTv4qbnGiTr3oJhkB1gsb6ToJQZ8uxGq2kaV2KL9650I1SJve dYm8Of8Zd621lSmoKOwlNClALZNew72NjJLEzTalU1OdT7/i1TXkH09XSSI8mEQ/ouNcMvIJ NwQpd369y9bfIhWUiVXEK7MlRgUG6MvIj6Y3Am/BBLUVbDa4+gmzDC9ezlZkTZG2t14zWPvx XP3FAp2pkW0xqG7/377qptDmrk42GlSKN4z76ELnLxussxc7I2hx18NUcbP8+uty4bMxABEB AAHNH0p1ZXJnZW4gR3Jvc3MgPGpncm9zc0BzdXNlLmNvbT7CwHkEEwECACMFAlOMcK8CGwMH CwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRCw3p3WKL8TL8eZB/9G0juS/kDY9LhEXseh mE9U+iA1VsLhgDqVbsOtZ/S14LRFHczNd/Lqkn7souCSoyWsBs3/wO+OjPvxf7m+Ef+sMtr0 G5lCWEWa9wa0IXx5HRPW/ScL+e4AVUbL7rurYMfwCzco+7TfjhMEOkC+va5gzi1KrErgNRHH kg3PhlnRY0Udyqx++UYkAsN4TQuEhNN32MvN0Np3WlBJOgKcuXpIElmMM5f1BBzJSKBkW0Jc Wy3h2Wy912vHKpPV/Xv7ZwVJ27v7KcuZcErtptDevAljxJtE7aJG6WiBzm+v9EswyWxwMCIO RoVBYuiocc51872tRGywc03xaQydB+9R7BHPzsBNBFOMcBYBCADLMfoA44MwGOB9YT1V4KCy vAfd7E0BTfaAurbG+Olacciz3yd09QOmejFZC6AnoykydyvTFLAWYcSCdISMr88COmmCbJzn sHAogjexXiif6ANUUlHpjxlHCCcELmZUzomNDnEOTxZFeWMTFF9Rf2k2F0Tl4E5kmsNGgtSa aMO0rNZoOEiD/7UfPP3dfh8JCQ1VtUUsQtT1sxos8Eb/HmriJhnaTZ7Hp3jtgTVkV0ybpgFg w6WMaRkrBh17mV0z2ajjmabB7SJxcouSkR0hcpNl4oM74d2/VqoW4BxxxOD1FcNCObCELfIS auZx+XT6s+CE7Qi/c44ibBMR7hyjdzWbABEBAAHCwF8EGAECAAkFAlOMcBYCGwwACgkQsN6d 1ii/Ey9D+Af/WFr3q+bg/8v5tCknCtn92d5lyYTBNt7xgWzDZX8G6/pngzKyWfedArllp0Pn fgIXtMNV+3t8Li1Tg843EXkP7+2+CQ98MB8XvvPLYAfW8nNDV85TyVgWlldNcgdv7nn1Sq8g HwB2BHdIAkYce3hEoDQXt/mKlgEGsLpzJcnLKimtPXQQy9TxUaLBe9PInPd+Ohix0XOlY+Uk QFEx50Ki3rSDl2Zt2tnkNYKUCvTJq7jvOlaPd6d/W0tZqpyy7KVay+K4aMobDsodB3dvEAs6 ScCnh03dDAFgIq5nsB11j3KPKdVoPlfucX2c7kGNH+LUMbzqV6beIENfNexkOfxHfw==
- Cc: jbeulich@xxxxxxxx, dfaggioli@xxxxxxxx, gwd@xxxxxxxxxxxxxx
- Delivery-date: Tue, 18 Aug 2026 10:14:01 +0000
- List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
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 <frn1furkan10@xxxxxxxxx>
---
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?
Your scenario is rare, but sadly we have no interlock to kill the domain
if a setmaxvcpus hypercall finishes mid-way through. Furthermore, for
dom0 at least, we actively do want to run in this configuration if we
end up in it, because that at least helps recovery of the system.
It is only about moving a domain to another cpupool. Dom0 can't be moved
anyway, and not being able to move a crippled domain is better than a crash.
So what is the problem then?
Juergen
Attachment:
OpenPGP_0xB0DE9DD628BF132F.asc
Description: OpenPGP public key
Attachment:
OpenPGP_signature.asc
Description: OpenPGP digital signature
|