From: "Roger Pau Monné" <roger.pau@citrix.com>
To: Alejandro Vallejo <alejandro.vallejo@cloud.com>
Cc: Xen-devel <xen-devel@lists.xenproject.org>,
Jan Beulich <jbeulich@suse.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Anthony PERARD <anthony@xenproject.org>
Subject: Re: [PATCH v2 7/8] xen/x86: Derive topologically correct x2APIC IDs from the policy
Date: Fri, 24 May 2024 10:39:25 +0200 [thread overview]
Message-ID: <ZlBSPYCpEAosNVzo@macbook> (raw)
In-Reply-To: <87a2a4589e330472b7260ff6ab513744596a4488.1715102098.git.alejandro.vallejo@cloud.com>
On Wed, May 08, 2024 at 01:39:26PM +0100, Alejandro Vallejo wrote:
> Implements the helper for mapping vcpu_id to x2apic_id given a valid
> topology in a policy. The algo is written with the intention of extending
> it to leaves 0x1f and e26 in the future.
Using 0x1f and e26 is kind of confusing. I would word as "0x1f and
extended leaf 0x26" to avoid confusion.
>
> Toolstack doesn't set leaf 0xb and the HVM default policy has it cleared,
> so the leaf is not implemented. In that case, the new helper just returns
> the legacy mapping.
>
> Signed-off-by: Alejandro Vallejo <alejandro.vallejo@cloud.com>
> ---
> v2:
> * const-ify the test definitions
> * Cosmetic changes (newline + parameter name in prototype)
> ---
> tools/tests/cpu-policy/test-cpu-policy.c | 63 ++++++++++++++++++++
> xen/include/xen/lib/x86/cpu-policy.h | 2 +
> xen/lib/x86/policy.c | 73 ++++++++++++++++++++++--
> 3 files changed, 133 insertions(+), 5 deletions(-)
>
> diff --git a/tools/tests/cpu-policy/test-cpu-policy.c b/tools/tests/cpu-policy/test-cpu-policy.c
> index 0ba8c418b1b3..82a6aeb23317 100644
> --- a/tools/tests/cpu-policy/test-cpu-policy.c
> +++ b/tools/tests/cpu-policy/test-cpu-policy.c
> @@ -776,6 +776,68 @@ static void test_topo_from_parts(void)
> }
> }
>
> +static void test_x2apic_id_from_vcpu_id_success(void)
> +{
> + static const struct test {
> + unsigned int vcpu_id;
> + unsigned int threads_per_core;
> + unsigned int cores_per_pkg;
> + uint32_t x2apic_id;
> + uint8_t x86_vendor;
> + } tests[] = {
> + {
> + .vcpu_id = 3, .threads_per_core = 3, .cores_per_pkg = 8,
> + .x2apic_id = 1 << 2,
> + },
> + {
> + .vcpu_id = 6, .threads_per_core = 3, .cores_per_pkg = 8,
> + .x2apic_id = 2 << 2,
> + },
> + {
> + .vcpu_id = 24, .threads_per_core = 3, .cores_per_pkg = 8,
> + .x2apic_id = 1 << 5,
> + },
> + {
> + .vcpu_id = 35, .threads_per_core = 3, .cores_per_pkg = 8,
> + .x2apic_id = (35 % 3) | (((35 / 3) % 8) << 2) | ((35 / 24) << 5),
> + },
> + {
> + .vcpu_id = 96, .threads_per_core = 7, .cores_per_pkg = 3,
> + .x2apic_id = (96 % 7) | (((96 / 7) % 3) << 3) | ((96 / 21) << 5),
^ extra space (same above)
> + },
> + };
> +
> + const uint8_t vendors[] = {
> + X86_VENDOR_INTEL,
> + X86_VENDOR_AMD,
> + X86_VENDOR_CENTAUR,
> + X86_VENDOR_SHANGHAI,
> + X86_VENDOR_HYGON,
> + };
> +
> + printf("Testing x2apic id from vcpu id success:\n");
> +
> + /* Perform the test run on every vendor we know about */
> + for ( size_t i = 0; i < ARRAY_SIZE(vendors); ++i )
> + {
> + struct cpu_policy policy = { .x86_vendor = vendors[i] };
Newline.
> + for ( size_t i = 0; i < ARRAY_SIZE(tests); ++i )
> + {
> + const struct test *t = &tests[i];
> + uint32_t x2apic_id;
> + int rc = x86_topo_from_parts(&policy, t->threads_per_core, t->cores_per_pkg);
Overly long line.
Won't it be better to define `policy` in this scope, so that for each
test you start with a clean policy, rather than having leftover data
from the previous test?
Also you could initialize x2apic_id at definition:
const struct test *t = &tests[j];
struct cpu_policy policy = { .x86_vendor = vendors[i] };
int rc = x86_topo_from_parts(&policy, t->threads_per_core, t->cores_per_pkg);
uint32_t x2apic_id = x86_x2apic_id_from_vcpu_id(&policy, t->vcpu_id);
> +
> + x2apic_id = x86_x2apic_id_from_vcpu_id(&policy, t->vcpu_id);
> + if ( rc || x2apic_id != t->x2apic_id )
> + fail("FAIL[%d] - '%s cpu%u %u t/c %u c/p'. bad x2apic_id: expected=%u actual=%u\n",
> + rc,
> + x86_cpuid_vendor_to_str(policy.x86_vendor),
> + t->vcpu_id, t->threads_per_core, t->cores_per_pkg,
> + t->x2apic_id, x2apic_id);
> + }
> + }
> +}
> +
> int main(int argc, char **argv)
> {
> printf("CPU Policy unit tests\n");
> @@ -794,6 +856,7 @@ int main(int argc, char **argv)
> test_is_compatible_failure();
>
> test_topo_from_parts();
> + test_x2apic_id_from_vcpu_id_success();
>
> if ( nr_failures )
> printf("Done: %u failures\n", nr_failures);
> diff --git a/xen/include/xen/lib/x86/cpu-policy.h b/xen/include/xen/lib/x86/cpu-policy.h
> index f5df18e9f77c..2cbc2726a861 100644
> --- a/xen/include/xen/lib/x86/cpu-policy.h
> +++ b/xen/include/xen/lib/x86/cpu-policy.h
> @@ -545,6 +545,8 @@ int x86_cpu_policies_are_compatible(const struct cpu_policy *host,
> /**
> * Calculates the x2APIC ID of a vCPU given a CPU policy
> *
> + * If the policy lacks leaf 0xb falls back to legacy mapping of apic_id=cpu*2
> + *
> * @param p CPU policy of the domain.
> * @param id vCPU ID of the vCPU.
> * @returns x2APIC ID of the vCPU.
> diff --git a/xen/lib/x86/policy.c b/xen/lib/x86/policy.c
> index d033ee5398dd..e498e32f8fd7 100644
> --- a/xen/lib/x86/policy.c
> +++ b/xen/lib/x86/policy.c
> @@ -2,15 +2,78 @@
>
> #include <xen/lib/x86/cpu-policy.h>
>
> +static uint32_t parts_per_higher_scoped_level(const struct cpu_policy *p, size_t lvl)
> +{
> + /*
> + * `nr_logical` reported by Intel is the number of THREADS contained in
> + * the next topological scope. For example, assuming a system with 2
> + * threads/core and 3 cores/module in a fully symmetric topology,
> + * `nr_logical` at the core level will report 6. Because it's reporting
> + * the number of threads in a module.
> + *
> + * On AMD/Hygon, nr_logical is already normalized by the higher scoped
> + * level (cores/complex, etc) so we can return it as-is.
> + */
> + if ( p->x86_vendor != X86_VENDOR_INTEL || !lvl )
> + return p->topo.subleaf[lvl].nr_logical;
> +
> + return p->topo.subleaf[lvl].nr_logical / p->topo.subleaf[lvl - 1].nr_logical;
Line length here and in the function declaration.
> +}
> +
> uint32_t x86_x2apic_id_from_vcpu_id(const struct cpu_policy *p, uint32_t id)
> {
> + uint32_t shift = 0, x2apic_id = 0;
> +
> + /* In the absence of topology leaves, fallback to traditional mapping */
> + if ( !p->topo.subleaf[0].type )
> + return id * 2;
> +
> /*
> - * TODO: Derive x2APIC ID from the topology information inside `p`
> - * rather than from vCPU ID. This bodge is a temporary measure
> - * until all infra is in place to retrieve or derive the initial
> - * x2APIC ID from migrated domains.
I'm a bit confused with this, the policy is domain wide, so we will
always need to pass the vCPU ID into x86_x2apic_id_from_vcpu_id()?
IOW: the x2APIC ID will always be derived from the vCPU ID.
Thanks, Roger.
next prev parent reply other threads:[~2024-05-24 8:39 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-08 12:39 [PATCH v2 0/8] x86: Expose consistent topology to guests Alejandro Vallejo
2024-05-08 12:39 ` [PATCH v2 1/8] xen/x86: Add initial x2APIC ID to the per-vLAPIC save area Alejandro Vallejo
2024-05-23 14:32 ` Roger Pau Monné
2024-05-24 10:58 ` Alejandro Vallejo
2024-05-24 11:15 ` Roger Pau Monné
2024-05-08 12:39 ` [PATCH v2 2/8] xen/x86: Simplify header dependencies in x86/hvm Alejandro Vallejo
2024-05-22 9:33 ` Jan Beulich
2024-05-22 15:24 ` Alejandro Vallejo
2024-05-23 14:37 ` Roger Pau Monné
2024-05-23 14:40 ` Jan Beulich
2024-05-23 14:52 ` Roger Pau Monné
2024-05-08 12:39 ` [PATCH v2 3/8] x86/vlapic: Move lapic_load_hidden migration checks to the check hook Alejandro Vallejo
2024-05-23 14:50 ` Roger Pau Monné
2024-05-24 11:16 ` Alejandro Vallejo
2024-05-24 12:53 ` Roger Pau Monné
2024-05-23 18:58 ` Andrew Cooper
2024-05-24 7:22 ` Roger Pau Monné
2024-05-08 12:39 ` [PATCH v2 4/8] tools/hvmloader: Wake APs with hypercalls and not with INIT+SIPI+SIPI Alejandro Vallejo
2024-05-08 19:13 ` Andrew Cooper
2024-05-09 11:04 ` Alejandro Vallejo
2024-05-09 17:50 ` [PATCH 4.5/8] tools/hvmloader: Further simplify SMP setup Andrew Cooper
2024-05-13 17:19 ` Alejandro Vallejo
2024-05-23 15:04 ` Roger Pau Monné
2024-05-08 12:39 ` [PATCH v2 5/8] tools/hvmloader: Retrieve (x2)APIC IDs from the APs themselves Alejandro Vallejo
2024-05-23 16:13 ` Roger Pau Monné
2024-05-24 15:16 ` Alejandro Vallejo
2024-05-27 8:55 ` Roger Pau Monné
2024-05-24 7:21 ` Roger Pau Monné
2024-05-24 15:15 ` Alejandro Vallejo
2024-05-27 8:52 ` Roger Pau Monné
2024-05-28 12:35 ` Alejandro Vallejo
2024-05-08 12:39 ` [PATCH v2 6/8] xen/lib: Add topology generator for x86 Alejandro Vallejo
2024-05-23 16:50 ` Roger Pau Monné
2024-05-28 13:28 ` Alejandro Vallejo
2024-05-08 12:39 ` [PATCH v2 7/8] xen/x86: Derive topologically correct x2APIC IDs from the policy Alejandro Vallejo
2024-05-24 8:39 ` Roger Pau Monné [this message]
2024-05-24 17:03 ` Alejandro Vallejo
2024-05-27 8:06 ` Roger Pau Monné
2024-05-08 12:39 ` [PATCH v2 8/8] xen/x86: Synthesise domain topologies Alejandro Vallejo
2024-05-24 8:58 ` Roger Pau Monné
2024-05-24 17:16 ` Alejandro Vallejo
2024-05-27 8:20 ` Roger Pau Monné
2024-05-28 14:06 ` Alejandro Vallejo
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=ZlBSPYCpEAosNVzo@macbook \
--to=roger.pau@citrix.com \
--cc=alejandro.vallejo@cloud.com \
--cc=andrew.cooper3@citrix.com \
--cc=anthony@xenproject.org \
--cc=jbeulich@suse.com \
--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.