• Artem Bityutskiy's avatar
    intel_idle: fix ACPI _CST matching for newer Xeon platforms · 4c411cca
    Artem Bityutskiy authored
    Background
    ~~~~~~~~~~
    
    The driver uses 'use_acpi = true' in C-state custom table for all Xeon
    platforms. The meaning of this flag is as follows.
    
     1. If a C-state from the custom table is defined in ACPI _CST (matched
        by the mwait hint), then enable this C-state.
    
     2. Otherwise, disable this C-state, unless the C-sate definition in the
        custom table has the 'CPUIDLE_FLAG_ALWAYS_ENABLE' flag set, in which
        case enabled it.
    
    The goal is to honor BIOS C6 settings - If BIOS disables C6, disable it
    by default in the OS too (but it can be enabled via sysfs).
    
    This works well on Xeons that expose only one flavor of C6. This are all
    Xeons except for the newest Granite Rapids (GNR) and Sierra Forest (SRF).
    
    The problem
    ~~~~~~~~~~~
    
    GNR and SRF have 2 flavors of C6: C6/C6P on GNR, C6S/C6SP on SRF. The
    the "P" flavor allows for the package C6, while the "non-P" flavor
    allows only for core/module C6.
    
    As far as this patch is concerned, both GNR and SRF platforms are
    handled the same way. Therefore, further discussion is focused on GNR,
    but it applies to SRF as well.
    
    On Intel Xeon platforms, BIOS exposes only 2 ACPI C-states: C1 and C2.
    Well, depending on BIOS settings, C2 may be named as C3. But there still
    will be only 2 states - C1 and C3. But this is a non-essential detail,
    so further discussion is focused on the ACPI C1 and C2 case.
    
    On pre-GNR/SRF Xeon platforms, ACPI C1 is mapped to C1 or C1E, and ACPI
    C2 is mapped to C6. The 'use_acpi' flag works just fine:
    
     * If ACPI C2 enabled, enable C6.
     * Otherwise, disable C6.
    
    However, on GNR there are 2 flavors of C6, so BIOS maps ACPI C2 to
    either C6 or C6P, depending on the user settings. As a result, due to
    the 'use_acpi' flag, 'intel_idle' disables least one of the C6 flavors.
    
    BIOS                   | OS                         | Verdict
    ----------------------------------------------------|---------
    ACPI C2 disabled       | C6 disabled, C6P disabled  | OK
    ACPI C2 mapped to C6   | C6 enabled,  C6P disabled  | Not OK
    ACPI C2 mapped to C6P  | C6 disabled, C6P enabled   | Not OK
    
    The goal of 'use_acpi' is to honor BIOS ACPI C2 disabled case, which
    works fine. But if ACPI C2 is enabled, the goal is to enable all flavors
    of C6, not just one of the flavors. This was overlooked when enabling
    GNR/SRF platforms.
    
    In other words, before GNR/SRF, the ACPI C2 status was binary - enabled
    or disabled. But it is not binary on GNR/SRF, however the goal is to
    continue treat it as binary.
    
    The fix
    ~~~~~~~
    
    Notice, that current algorithm matches ACPI and custom table C-states
    by the mwait hint. However, mwait hint consists of the 'state' and
    'sub-state' parts, and all C6 flavors have the same state value of 0x20,
    but different sub-state values.
    
    Introduce new C-state table flag - CPUIDLE_FLAG_PARTIAL_HINT_MATCH and
    add it to both C6 flavors of the GNR/SRF platforms.
    
    When matching ACPI _CST and custom table C-states, match only the start
    part if the C-state has CPUIDLE_FLAG_PARTIAL_HINT_MATCH, other wise
    match both state and sub-state parts (as before).
    
    With this fix, GNR C-states enabled/disabled status looks like this.
    
    BIOS                   | OS
    ----------------------------------------------------
    ACPI C2 disabled       | C6 disabled, C6P disabled
    ACPI C2 mapped to C6   | C6 enabled, C6P enabled
    ACPI C2 mapped to C6P  | C6 enabled, C6P enabled
    
    Possible alternative
    ~~~~~~~~~~~~~~~~~~~~
    
    The alternative would be to remove 'use_acpi' flag for GNR and SRF.
    This would be a simpler solution, but it would violate the principle of
    least surprise - users of Xeon platforms are used to the fact that
    intel_idle honors C6 enabled/disabled flag. It is more consistent user
    experience if GNR/SRF continue doing so.
    
    How tested
    ~~~~~~~~~~
    
    Tested on GNR and SRF platform with all the 3 BIOS configurations: ACPI
    C2 disabled, mapped to C6/C6S, mapped to C6P/C6SP.
    
    Tested on Ice lake Xeon and Sapphire Rapids Xeon platforms with ACPI C2
    enabled and disabled, just to verify that the patch does not break older
    Xeons.
    
    Fixes: 92813fd5 ("intel_idle: add Sierra Forest SoC support")
    Fixes: 370406bf ("intel_idle: add Granite Rapids Xeon support")
    Cc: 6.8+ <stable@vger.kernel.org> # 6.8+
    Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
    Link: https://patch.msgid.link/20240913165143.4140073-1-dedekind1@gmail.com
    [ rjw: Changelog edits ]
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    4c411cca
intel_idle.c 61.4 KB