[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v2 04/23] x86: Don't use potentially incorrect CPUID values for topology information



Jan Beulich:
> On 07.08.2023 11:58, Simon Gaiser wrote:
>> Jan Beulich:
>>> On 07.08.2023 10:18, Simon Gaiser wrote:
>>>> Anthony Liguori:
>>>>> From: Jan H. Schönherr <jschoenh@xxxxxxxxx>
>>>>>
>>>>> Intel says for CPUID leaf 0Bh:
>>>>>
>>>>>   "Software must not use EBX[15:0] to enumerate processor
>>>>>    topology of the system. This value in this field
>>>>>    (EBX[15:0]) is only intended for display/diagnostic
>>>>>    purposes. The actual number of logical processors
>>>>>    available to BIOS/OS/Applications may be different from
>>>>>    the value of EBX[15:0], depending on software and platform
>>>>>    hardware configurations."
>>>>>
>>>>> And yet, we're using them to derive the number cores in a package
>>>>> and the number of siblings in a core.
>>>>>
>>>>> Derive the number of siblings and cores from EAX instead, which is
>>>>> intended for that.
>>>>>
>>>>> Signed-off-by: Jan H. Schönherr <jschoenh@xxxxxxxxx>
>>>>> ---
>>>>>  xen/arch/x86/cpu/common.c | 4 ++--
>>>>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
>>>>> index e9588b3..22f392f 100644
>>>>> --- a/xen/arch/x86/cpu/common.c
>>>>> +++ b/xen/arch/x86/cpu/common.c
>>>>> @@ -479,8 +479,8 @@ void detect_extended_topology(struct cpuinfo_x86 *c)
>>>>>     initial_apicid = edx;
>>>>>  
>>>>>     /* Populate HT related information from sub-leaf level 0 */
>>>>> -   core_level_siblings = c->x86_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
>>>>>     core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
>>>>> +   core_level_siblings = c->x86_num_siblings = 1 << ht_mask_width;
>>>>>  
>>>>>     sub_index = 1;
>>>>>     do {
>>>>> @@ -488,8 +488,8 @@ void detect_extended_topology(struct cpuinfo_x86 *c)
>>>>>  
>>>>>             /* Check for the Core type in the implemented sub leaves */
>>>>>             if ( LEAFB_SUBTYPE(ecx) == CORE_TYPE ) {
>>>>> -                   core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
>>>>>                     core_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
>>>>> +                   core_level_siblings = 1 << core_plus_mask_width;
>>>>
>>>>
>>>> On the i5-1135G7 (4 cores with each 2 threads) I'm currently testing on
>>>> I noticed that this changes leads to core_level_siblings == 16 and
>>>> therefore x86_max_cores == 8. If read from ebx like before this change
>>>> and what Linux is still doing [1] it reads core_level_siblings == 8 (as
>>>> expected?).
>>>>
>>>> What's the expected semantic here? If it's to derive the actual number
>>>> of siblings (and therefore cores) in a package as the commit message
>>>> suggest, the new code can't work even ignoring the example from my test
>>>> system. It will always produce powers of 2, so can't get it right on a
>>>> system with, say, 6 cores.
>>>
>>> The only use of the variable in question is in this statement:
>>>
>>>       c->x86_max_cores = (core_level_siblings / c->x86_num_siblings);
>>>
>>> Note the "max" in the name. This is how many _could_ be there, not how
>>> many _are_ there, aiui.
>>
>> I'm indeed not quite sure on the intended semantic, hence the question
>> (although it's not clear to me what case that "could" would cover here).
> 
> "Could" covers for a number of reasons why APIC IDs may not be contiguous.
> Consider a 6-code system: The APIC IDs need to cover for at least 8 there.
> 
>> It doesn't have to be identical but Linux says for it's version of the
>> variable:
>>
>>     The number of cores in a package. This information is retrieved via
>>     CPUID.
>>
>> And if I look at it's usage in set_nr_sockets in Xen:
>>
>>     nr_sockets = last_physid(phys_cpu_present_map)
>>                  / boot_cpu_data.x86_max_cores
>>                  / boot_cpu_data.x86_num_siblings + 1;
> 
> This validly uses the field in the "max" sense, not in the "actual" one.

I see, both cases cover APIC IDs not just numbers of logical CPUs.
Thanks for the explanation and the pointer from Andrew in his response.

I just had noticed the, to me, unexpected value, while debugging
something. But based on this explanation things are actually working
as intended here. (The actual problem I was looking for it turned out
to be [1].)

[1]: 
https://lore.kernel.org/xen-devel/7f158a54548456daba9f2e105d099d2e5e2c2f38.1691399031.git.simon@xxxxxxxxxxxxxxxxxxxxxx/

>> It seems to be also be used in this meaning. At least on my test system
>> I get last_physid == 7 (as I would have expected for 8 logical cpus). So
>> dividing this by the 4 (number of cores) and 2 (threads per core) is
>> what I think was intended here.
> 
> Would you mind providing raw data from your system: Both the raw CPUID
> output for the leaf/leaves of interest here and the APIC IDs of all
> threads?

Sure:

From attached patch:

(XEN) dbg smp_processor_id() = 0
(XEN) dbg get_apic_id() = 0
(XEN) dbg cpuid_count(0xb, SMT_LEVEL) = 0x1, 0x2, 0x100, 0
(XEN) dbg cpuid_count(0xb, 0x1) = 0x4, 0x8, 0x201, 0

(XEN) dbg smp_processor_id() = 1
(XEN) dbg get_apic_id() = 1
(XEN) dbg cpuid_count(0xb, SMT_LEVEL) = 0x1, 0x2, 0x100, 0x1
(XEN) dbg cpuid_count(0xb, 0x1) = 0x4, 0x8, 0x201, 0x1

(XEN) dbg smp_processor_id() = 2
(XEN) dbg get_apic_id() = 2
(XEN) dbg cpuid_count(0xb, SMT_LEVEL) = 0x1, 0x2, 0x100, 0x2
(XEN) dbg cpuid_count(0xb, 0x1) = 0x4, 0x8, 0x201, 0x2

(XEN) dbg smp_processor_id() = 3
(XEN) dbg get_apic_id() = 3
(XEN) dbg cpuid_count(0xb, SMT_LEVEL) = 0x1, 0x2, 0x100, 0x3
(XEN) dbg cpuid_count(0xb, 0x1) = 0x4, 0x8, 0x201, 0x3

(XEN) dbg smp_processor_id() = 4
(XEN) dbg get_apic_id() = 4
(XEN) dbg cpuid_count(0xb, SMT_LEVEL) = 0x1, 0x2, 0x100, 0x4
(XEN) dbg cpuid_count(0xb, 0x1) = 0x4, 0x8, 0x201, 0x4

(XEN) dbg smp_processor_id() = 5
(XEN) dbg get_apic_id() = 5
(XEN) dbg cpuid_count(0xb, SMT_LEVEL) = 0x1, 0x2, 0x100, 0x5
(XEN) dbg cpuid_count(0xb, 0x1) = 0x4, 0x8, 0x201, 0x5

(XEN) dbg smp_processor_id() = 6
(XEN) dbg get_apic_id() = 6
(XEN) dbg cpuid_count(0xb, SMT_LEVEL) = 0x1, 0x2, 0x100, 0x6
(XEN) dbg cpuid_count(0xb, 0x1) = 0x4, 0x8, 0x201, 0x6

(XEN) dbg smp_processor_id() = 7
(XEN) dbg get_apic_id() = 7
(XEN) dbg cpuid_count(0xb, SMT_LEVEL) = 0x1, 0x2, 0x100, 0x7
(XEN) dbg cpuid_count(0xb, 0x1) = 0x4, 0x8, 0x201, 0x7

From the MADT table:

[02Ch 0044   1]                Subtable Type : 00 [Processor Local APIC]
[02Dh 0045   1]                       Length : 08
[02Eh 0046   1]                 Processor ID : 00
[02Fh 0047   1]                Local Apic ID : 00
[030h 0048   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1
                      Runtime Online Capable : 0

[034h 0052   1]                Subtable Type : 00 [Processor Local APIC]
[035h 0053   1]                       Length : 08
[036h 0054   1]                 Processor ID : 01
[037h 0055   1]                Local Apic ID : 02
[038h 0056   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1
                      Runtime Online Capable : 0

[03Ch 0060   1]                Subtable Type : 00 [Processor Local APIC]
[03Dh 0061   1]                       Length : 08
[03Eh 0062   1]                 Processor ID : 02
[03Fh 0063   1]                Local Apic ID : 04
[040h 0064   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1
                      Runtime Online Capable : 0

[044h 0068   1]                Subtable Type : 00 [Processor Local APIC]
[045h 0069   1]                       Length : 08
[046h 0070   1]                 Processor ID : 03
[047h 0071   1]                Local Apic ID : 06
[048h 0072   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1
                      Runtime Online Capable : 0

[04Ch 0076   1]                Subtable Type : 00 [Processor Local APIC]
[04Dh 0077   1]                       Length : 08
[04Eh 0078   1]                 Processor ID : 04
[04Fh 0079   1]                Local Apic ID : 01
[050h 0080   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1
                      Runtime Online Capable : 0

[054h 0084   1]                Subtable Type : 00 [Processor Local APIC]
[055h 0085   1]                       Length : 08
[056h 0086   1]                 Processor ID : 05
[057h 0087   1]                Local Apic ID : 03
[058h 0088   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1
                      Runtime Online Capable : 0

[05Ch 0092   1]                Subtable Type : 00 [Processor Local APIC]
[05Dh 0093   1]                       Length : 08
[05Eh 0094   1]                 Processor ID : 06
[05Fh 0095   1]                Local Apic ID : 05
[060h 0096   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1
                      Runtime Online Capable : 0

[064h 0100   1]                Subtable Type : 00 [Processor Local APIC]
[065h 0101   1]                       Length : 08
[066h 0102   1]                 Processor ID : 07
[067h 0103   1]                Local Apic ID : 07
[068h 0104   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1
                      Runtime Online Capable : 0

[06Ch 0108   1]                Subtable Type : 00 [Processor Local APIC]
[06Dh 0109   1]                       Length : 08
[06Eh 0110   1]                 Processor ID : 08
[06Fh 0111   1]                Local Apic ID : FF
[070h 0112   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0
                      Runtime Online Capable : 0

[074h 0116   1]                Subtable Type : 00 [Processor Local APIC]
[075h 0117   1]                       Length : 08
[076h 0118   1]                 Processor ID : 09
[077h 0119   1]                Local Apic ID : FF
[078h 0120   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0
                      Runtime Online Capable : 0

[07Ch 0124   1]                Subtable Type : 00 [Processor Local APIC]
[07Dh 0125   1]                       Length : 08
[07Eh 0126   1]                 Processor ID : 0A
[07Fh 0127   1]                Local Apic ID : FF
[080h 0128   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0
                      Runtime Online Capable : 0

[084h 0132   1]                Subtable Type : 00 [Processor Local APIC]
[085h 0133   1]                       Length : 08
[086h 0134   1]                 Processor ID : 0B
[087h 0135   1]                Local Apic ID : FF
[088h 0136   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0
                      Runtime Online Capable : 0

[08Ch 0140   1]                Subtable Type : 00 [Processor Local APIC]
[08Dh 0141   1]                       Length : 08
[08Eh 0142   1]                 Processor ID : 0C
[08Fh 0143   1]                Local Apic ID : FF
[090h 0144   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0
                      Runtime Online Capable : 0

[094h 0148   1]                Subtable Type : 00 [Processor Local APIC]
[095h 0149   1]                       Length : 08
[096h 0150   1]                 Processor ID : 0D
[097h 0151   1]                Local Apic ID : FF
[098h 0152   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0
                      Runtime Online Capable : 0

[09Ch 0156   1]                Subtable Type : 00 [Processor Local APIC]
[09Dh 0157   1]                       Length : 08
[09Eh 0158   1]                 Processor ID : 0E
[09Fh 0159   1]                Local Apic ID : FF
[0A0h 0160   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0
                      Runtime Online Capable : 0

[0A4h 0164   1]                Subtable Type : 00 [Processor Local APIC]
[0A5h 0165   1]                       Length : 08
[0A6h 0166   1]                 Processor ID : 0F
[0A7h 0167   1]                Local Apic ID : FF
[0A8h 0168   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0
                      Runtime Online Capable : 0

If you wanted something else or need more, just let me know.

Simon

Attachment: detect_extended_topology-dbg.patch
Description: Text Data

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.