From: "Roger Pau Monné" <roger.pau@citrix.com>
To: Alejandro Vallejo <alejandro.vallejo@cloud.com>
Cc: Xen-devel <xen-devel@lists.xenproject.org>, Wei Liu <wl@xen.org>,
Anthony PERARD <anthony.perard@citrix.com>,
Juergen Gross <jgross@suse.com>, Jan Beulich <jbeulich@suse.com>,
Andrew Cooper <andrew.cooper3@citrix.com>
Subject: Re: [PATCH 6/6] xen/x86: Add topology generator
Date: Wed, 20 Mar 2024 11:29:50 +0100 [thread overview]
Message-ID: <Zfq6np1--SxKGE30@macbook> (raw)
In-Reply-To: <20240109153834.4192-7-alejandro.vallejo@cloud.com>
On Tue, Jan 09, 2024 at 03:38:34PM +0000, Alejandro Vallejo wrote:
> This allows toolstack to synthesise sensible topologies for guests. In
> particular, this patch causes x2APIC IDs to be packed according to the
> topology now exposed to the guests on leaf 0xb.
>
> Signed-off-by: Alejandro Vallejo <alejandro.vallejo@cloud.com>
> ---
> tools/include/xenguest.h | 15 ++++
> tools/libs/guest/xg_cpuid_x86.c | 144 ++++++++++++++++++++------------
> xen/arch/x86/cpu-policy.c | 6 +-
> 3 files changed, 107 insertions(+), 58 deletions(-)
>
> diff --git a/tools/include/xenguest.h b/tools/include/xenguest.h
> index 4e9078fdee..f0043c559b 100644
> --- a/tools/include/xenguest.h
> +++ b/tools/include/xenguest.h
> @@ -843,5 +843,20 @@ enum xc_static_cpu_featuremask {
> XC_FEATUREMASK_HVM_HAP_DEF,
> };
> const uint32_t *xc_get_static_cpu_featuremask(enum xc_static_cpu_featuremask);
> +
> +/**
> + * Synthesise topology information in `p` given high-level constraints
> + *
> + * Topology is given in various fields accross several leaves, some of
> + * which are vendor-specific. This function uses the policy itself to
> + * derive such leaves from threads/core and cores/package.
> + *
> + * @param p CPU policy of the domain.
> + * @param threads_per_core threads/core. Doesn't need to be a power of 2.
> + * @param cores_per_package cores/package. Doesn't need to be a power of 2.
> + */
> +void xc_topo_from_parts(struct cpu_policy *p,
> + uint32_t threads_per_core, uint32_t cores_per_pkg);
I think you can use plain unsigned int here.
> +
> #endif /* __i386__ || __x86_64__ */
> #endif /* XENGUEST_H */
> diff --git a/tools/libs/guest/xg_cpuid_x86.c b/tools/libs/guest/xg_cpuid_x86.c
> index 4453178100..7a622721be 100644
> --- a/tools/libs/guest/xg_cpuid_x86.c
> +++ b/tools/libs/guest/xg_cpuid_x86.c
> @@ -584,7 +584,7 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore,
> bool hvm;
> xc_domaininfo_t di;
> struct xc_cpu_policy *p = xc_cpu_policy_init();
> - unsigned int i, nr_leaves = ARRAY_SIZE(p->leaves), nr_msrs = 0;
> + unsigned int nr_leaves = ARRAY_SIZE(p->leaves), nr_msrs = 0;
> uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1;
> uint32_t host_featureset[FEATURESET_NR_ENTRIES] = {};
> uint32_t len = ARRAY_SIZE(host_featureset);
> @@ -727,60 +727,8 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore,
> }
> else
> {
> - /*
> - * Topology for HVM guests is entirely controlled by Xen. For now, we
> - * hardcode APIC_ID = vcpu_id * 2 to give the illusion of no SMT.
> - */
> - p->policy.basic.htt = true;
> - p->policy.extd.cmp_legacy = false;
> -
> - /*
> - * Leaf 1 EBX[23:16] is Maximum Logical Processors Per Package.
> - * Update to reflect vLAPIC_ID = vCPU_ID * 2, but make sure to avoid
> - * overflow.
> - */
> - if ( !p->policy.basic.lppp )
> - p->policy.basic.lppp = 2;
> - else if ( !(p->policy.basic.lppp & 0x80) )
> - p->policy.basic.lppp *= 2;
> -
> - switch ( p->policy.x86_vendor )
> - {
> - case X86_VENDOR_INTEL:
> - for ( i = 0; (p->policy.cache.subleaf[i].type &&
> - i < ARRAY_SIZE(p->policy.cache.raw)); ++i )
> - {
> - p->policy.cache.subleaf[i].cores_per_package =
> - (p->policy.cache.subleaf[i].cores_per_package << 1) | 1;
> - p->policy.cache.subleaf[i].threads_per_cache = 0;
> - }
> - break;
> -
> - case X86_VENDOR_AMD:
> - case X86_VENDOR_HYGON:
> - /*
> - * Leaf 0x80000008 ECX[15:12] is ApicIdCoreSize.
> - * Leaf 0x80000008 ECX[7:0] is NumberOfCores (minus one).
> - * Update to reflect vLAPIC_ID = vCPU_ID * 2. But avoid
> - * - overflow,
> - * - going out of sync with leaf 1 EBX[23:16],
> - * - incrementing ApicIdCoreSize when it's zero (which changes the
> - * meaning of bits 7:0).
> - *
> - * UPDATE: I addition to avoiding overflow, some
> - * proprietary operating systems have trouble with
> - * apic_id_size values greater than 7. Limit the value to
> - * 7 for now.
> - */
> - if ( p->policy.extd.nc < 0x7f )
> - {
> - if ( p->policy.extd.apic_id_size != 0 && p->policy.extd.apic_id_size < 0x7 )
> - p->policy.extd.apic_id_size++;
> -
> - p->policy.extd.nc = (p->policy.extd.nc << 1) | 1;
> - }
> - break;
> - }
> + /* TODO: Expose the ability to choose a custom topology for HVM/PVH */
> + xc_topo_from_parts(&p->policy, 1, di.max_vcpu_id + 1);
It would be better if this was split into two commits. First commit
would move the code as-is into xc_topo_from_parts() without any
changes. Second patch would do the functional changes. That was it's
far easier to spot what are the relevant changes vs pure code
movement.
> }
>
> nr_leaves = ARRAY_SIZE(p->leaves);
> @@ -1028,3 +976,89 @@ bool xc_cpu_policy_is_compatible(xc_interface *xch, xc_cpu_policy_t *host,
>
> return false;
> }
> +
> +static uint32_t order(uint32_t n)
> +{
> + return 32 - __builtin_clz(n);
> +}
> +
> +void xc_topo_from_parts(struct cpu_policy *p,
> + uint32_t threads_per_core, uint32_t cores_per_pkg)
> +{
> + uint32_t threads_per_pkg = threads_per_core * cores_per_pkg;
> + uint32_t apic_id_size;
> +
> + if ( p->basic.max_leaf < 0xb )
> + p->basic.max_leaf = 0xb;
> +
> + memset(p->topo.raw, 0, sizeof(p->topo.raw));
> +
> + /* thread level */
> + p->topo.subleaf[0].nr_logical = threads_per_core;
> + p->topo.subleaf[0].id_shift = 0;
> + p->topo.subleaf[0].level = 0;
> + p->topo.subleaf[0].type = 1;
> + if ( threads_per_core > 1 )
> + p->topo.subleaf[0].id_shift = order(threads_per_core - 1);
> +
> + /* core level */
> + p->topo.subleaf[1].nr_logical = cores_per_pkg;
> + if ( p->x86_vendor == X86_VENDOR_INTEL )
> + p->topo.subleaf[1].nr_logical = threads_per_pkg;
> + p->topo.subleaf[1].id_shift = p->topo.subleaf[0].id_shift;
> + p->topo.subleaf[1].level = 1;
> + p->topo.subleaf[1].type = 2;
> + if ( cores_per_pkg > 1 )
> + p->topo.subleaf[1].id_shift += order(cores_per_pkg - 1);
I was kind of expecting this to be part of cpu-policy rather than xc,
as we could then also test this like you do test
x86_x2apic_id_from_vcpu_id().
It could also be used to populate the topologies in the tests
themselves.
Thanks, Roger.
next prev parent reply other threads:[~2024-03-20 10:30 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-09 15:38 [PATCH 0/6] x86: Expose consistent topology to guests Alejandro Vallejo
2024-01-09 15:38 ` [PATCH 1/6] xen/x86: Add initial x2APIC ID to the per-vLAPIC save area Alejandro Vallejo
2024-03-19 16:20 ` Roger Pau Monné
2024-03-20 9:33 ` Roger Pau Monné
2024-03-25 16:56 ` Alejandro Vallejo
2024-03-25 15:44 ` Alejandro Vallejo
2024-03-25 16:45 ` Jan Beulich
2024-03-25 18:00 ` Alejandro Vallejo
2024-03-26 7:16 ` Jan Beulich
2024-01-09 15:38 ` [PATCH 2/6] tools/xc: Add xc_cpu_policy to the public xenctrl.h header Alejandro Vallejo
2024-03-19 17:55 ` Roger Pau Monné
2024-03-25 18:19 ` Alejandro Vallejo
2024-01-09 15:38 ` [PATCH 3/6] xen/x86: Refactor xen/lib/x86 so it can be linked in hvmloader Alejandro Vallejo
2024-03-25 16:55 ` Jan Beulich
2024-01-09 15:38 ` [PATCH 4/6] tools/hvmloader: Use cpu_policy to determine APIC IDs Alejandro Vallejo
2024-03-20 8:52 ` Roger Pau Monné
2024-03-25 17:00 ` Jan Beulich
2024-01-09 15:38 ` [PATCH 5/6] xen/x86: Derive topologically correct x2APIC IDs from the policy Alejandro Vallejo
2024-03-20 10:15 ` Roger Pau Monné
2024-05-01 16:05 ` Alejandro Vallejo
2024-03-26 16:41 ` Jan Beulich
2024-05-01 16:35 ` Alejandro Vallejo
2024-05-02 6:55 ` Jan Beulich
2024-05-02 6:57 ` Jan Beulich
2024-05-02 14:44 ` Alejandro Vallejo
2024-01-09 15:38 ` [PATCH 6/6] xen/x86: Add topology generator Alejandro Vallejo
2024-01-10 14:16 ` Alejandro Vallejo
2024-01-10 14:28 ` Jan Beulich
2024-03-20 10:29 ` Roger Pau Monné [this message]
2024-03-26 17:02 ` Jan Beulich
2024-05-01 17:06 ` Alejandro Vallejo
2024-05-02 7:13 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Zfq6np1--SxKGE30@macbook \
--to=roger.pau@citrix.com \
--cc=alejandro.vallejo@cloud.com \
--cc=andrew.cooper3@citrix.com \
--cc=anthony.perard@citrix.com \
--cc=jbeulich@suse.com \
--cc=jgross@suse.com \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.