lkml.org 
[lkml]   [2022]   [Aug]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/7] x86/topology: Fix multiple packages shown on a single-package system
    Date
    CPUID.1F/B does not emumerate Package level explicitly, instead, all the
    APICID bits above the enumerated levels are assumed to be package id bits.

    Current code gets package id by shifting out all the APICID bits that
    Linux supports, rather than shifting out all the APICID bits that CPUID.1F
    enumerates. This introduces problems when CPUID.1F enumerates a level that
    Linux does not support.

    For example, on an AlderLake-N platform, there are 2 Ecore Modules, which
    has 4 atom cores in each module, in a single package.
    Linux does not support Module level and interprets the Module id bits as
    package id and erroneously reports a multi module system as a multi-package
    system.

    Fix this by using APICID bits above all the CPUID.1F enumerated levels as
    package id.

    Suggested-and-reviewed-by: Len Brown <len.brown@intel.com>
    Signed-off-by: Zhang Rui <rui.zhang@intel.com>
    ---
    arch/x86/kernel/cpu/topology.c | 14 ++++++++++----
    1 file changed, 10 insertions(+), 4 deletions(-)

    diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c
    index 132a2de44d2f..f7592814e5d5 100644
    --- a/arch/x86/kernel/cpu/topology.c
    +++ b/arch/x86/kernel/cpu/topology.c
    @@ -96,6 +96,7 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
    unsigned int ht_mask_width, core_plus_mask_width, die_plus_mask_width;
    unsigned int core_select_mask, core_level_siblings;
    unsigned int die_select_mask, die_level_siblings;
    + unsigned int pkg_mask_width;
    bool die_level_present = false;
    int leaf;

    @@ -111,10 +112,10 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
    core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
    core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
    die_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
    - die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
    + pkg_mask_width = die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);

    sub_index = 1;
    - do {
    + while (true) {
    cpuid_count(leaf, sub_index, &eax, &ebx, &ecx, &edx);

    /*
    @@ -132,8 +133,13 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
    die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
    }

    + if (LEAFB_SUBTYPE(ecx) != INVALID_TYPE)
    + pkg_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
    + else
    + break;
    +
    sub_index++;
    - } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE);
    + }

    core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width;
    die_select_mask = (~(-1 << die_plus_mask_width)) >>
    @@ -148,7 +154,7 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
    }

    c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid,
    - die_plus_mask_width);
    + pkg_mask_width);
    /*
    * Reinit the apicid, now that we have extended initial_apicid.
    */
    --
    2.34.1
    \
     
     \ /
      Last update: 2022-08-12 18:38    [W:3.408 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site