linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rafael@kernel.org>
To: Zhang Rui <rui.zhang@intel.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>,
	Linux PM <linux-pm@vger.kernel.org>,
	Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Subject: Re: [PATCH] intel_idle: add AlderLake support
Date: Fri, 22 Apr 2022 15:53:46 +0200	[thread overview]
Message-ID: <CAJZ5v0jEFX-iv=NagN0MxYWEOGWjP5qbgPh=PL9wg5dUKDQiaQ@mail.gmail.com> (raw)
In-Reply-To: <20220415093951.2677170-1-rui.zhang@intel.com>

On Fri, Apr 15, 2022 at 11:40 AM Zhang Rui <rui.zhang@intel.com> wrote:
>
> Similar to SPR, the C1 and C1E states on ADL are mutually exclusive.
> Only one of them can be enabled at one time.
> But contrast to SPR, which usually has a strong latency requirement as a
> Xeon processor, C1E is preferred on ADL from the power' perspective of
> view.
>
> This patch adds both C1 and C1E states in the custom table, and
> 1. enables the "C1E promotion" bit in 'MSR_IA32_POWER_CTL' and mark C1
>    with the "CPUIDLE_FLAG_UNUSABLE" flag, thus C1 is not available by
>    default from both hardware and software.
> 2. adds support for "preferred_cstates" module parameter, so that user
>    can choose C1 instead of C1E by booting with
>    "intel_idle.preferred_cstates=2".
>
> Plus, separate custom cstate tables are introduced for the ADL mobile and
> desktop processors, because of the latency differences between these two
> processors, especially in PC10.
>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Applied as 5.19 material with some edits in the chamgelog, thanks!

> ---
>  drivers/idle/intel_idle.c | 137 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 137 insertions(+)
>
> diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
> index b7640cfe0020..f738d08dc961 100644
> --- a/drivers/idle/intel_idle.c
> +++ b/drivers/idle/intel_idle.c
> @@ -759,6 +759,106 @@ static struct cpuidle_state icx_cstates[] __initdata = {
>                 .enter = NULL }
>  };
>
> +/*
> + * On AlderLake C1 has to be disabled if C1E is enabled, and vice versa.
> + * C1E is enabled only if "C1E promotion" bit is set in MSR_IA32_POWER_CTL.
> + * But in this case there is effectively no C1, because C1 requests are
> + * promoted to C1E. If the "C1E promotion" bit is cleared, then both C1
> + * and C1E requests end up with C1, so there is effectively no C1E.
> + *
> + * By default we enable C1E and disable C1 by marking it with
> + * 'CPUIDLE_FLAG_UNUSABLE'.
> + */
> +static struct cpuidle_state adl_cstates[] __initdata = {
> +       {
> +               .name = "C1",
> +               .desc = "MWAIT 0x00",
> +               .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_UNUSABLE,
> +               .exit_latency = 1,
> +               .target_residency = 1,
> +               .enter = &intel_idle,
> +               .enter_s2idle = intel_idle_s2idle, },
> +       {
> +               .name = "C1E",
> +               .desc = "MWAIT 0x01",
> +               .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
> +               .exit_latency = 2,
> +               .target_residency = 4,
> +               .enter = &intel_idle,
> +               .enter_s2idle = intel_idle_s2idle, },
> +       {
> +               .name = "C6",
> +               .desc = "MWAIT 0x20",
> +               .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
> +               .exit_latency = 220,
> +               .target_residency = 600,
> +               .enter = &intel_idle,
> +               .enter_s2idle = intel_idle_s2idle, },
> +       {
> +               .name = "C8",
> +               .desc = "MWAIT 0x40",
> +               .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
> +               .exit_latency = 280,
> +               .target_residency = 800,
> +               .enter = &intel_idle,
> +               .enter_s2idle = intel_idle_s2idle, },
> +       {
> +               .name = "C10",
> +               .desc = "MWAIT 0x60",
> +               .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
> +               .exit_latency = 680,
> +               .target_residency = 2000,
> +               .enter = &intel_idle,
> +               .enter_s2idle = intel_idle_s2idle, },
> +       {
> +               .enter = NULL }
> +};
> +
> +static struct cpuidle_state adl_l_cstates[] __initdata = {
> +       {
> +               .name = "C1",
> +               .desc = "MWAIT 0x00",
> +               .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_UNUSABLE,
> +               .exit_latency = 1,
> +               .target_residency = 1,
> +               .enter = &intel_idle,
> +               .enter_s2idle = intel_idle_s2idle, },
> +       {
> +               .name = "C1E",
> +               .desc = "MWAIT 0x01",
> +               .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
> +               .exit_latency = 2,
> +               .target_residency = 4,
> +               .enter = &intel_idle,
> +               .enter_s2idle = intel_idle_s2idle, },
> +       {
> +               .name = "C6",
> +               .desc = "MWAIT 0x20",
> +               .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
> +               .exit_latency = 170,
> +               .target_residency = 500,
> +               .enter = &intel_idle,
> +               .enter_s2idle = intel_idle_s2idle, },
> +       {
> +               .name = "C8",
> +               .desc = "MWAIT 0x40",
> +               .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
> +               .exit_latency = 200,
> +               .target_residency = 600,
> +               .enter = &intel_idle,
> +               .enter_s2idle = intel_idle_s2idle, },
> +       {
> +               .name = "C10",
> +               .desc = "MWAIT 0x60",
> +               .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
> +               .exit_latency = 230,
> +               .target_residency = 700,
> +               .enter = &intel_idle,
> +               .enter_s2idle = intel_idle_s2idle, },
> +       {
> +               .enter = NULL }
> +};
> +
>  /*
>   * On Sapphire Rapids Xeon C1 has to be disabled if C1E is enabled, and vice
>   * versa. On SPR C1E is enabled only if "C1E promotion" bit is set in
> @@ -1142,6 +1242,14 @@ static const struct idle_cpu idle_cpu_icx __initconst = {
>         .use_acpi = true,
>  };
>
> +static const struct idle_cpu idle_cpu_adl __initconst = {
> +       .state_table = adl_cstates,
> +};
> +
> +static const struct idle_cpu idle_cpu_adl_l __initconst = {
> +       .state_table = adl_l_cstates,
> +};
> +
>  static const struct idle_cpu idle_cpu_spr __initconst = {
>         .state_table = spr_cstates,
>         .disable_promotion_to_c1e = true,
> @@ -1210,6 +1318,8 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
>         X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X,           &idle_cpu_skx),
>         X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X,           &idle_cpu_icx),
>         X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D,           &idle_cpu_icx),
> +       X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE,           &idle_cpu_adl),
> +       X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L,         &idle_cpu_adl_l),
>         X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X,    &idle_cpu_spr),
>         X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL,        &idle_cpu_knl),
>         X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM,        &idle_cpu_knl),
> @@ -1570,6 +1680,29 @@ static void __init skx_idle_state_table_update(void)
>         }
>  }
>
> +/**
> + * adl_idle_state_table_update - Adjust AlderLake idle states table.
> + */
> +static void __init adl_idle_state_table_update(void)
> +{
> +       /* Check if user prefers C1 over C1E. */
> +       if (preferred_states_mask & BIT(1)) {
> +               if (preferred_states_mask & BIT(2))
> +                       /* Both can't be enabled, stick to the defaults. */
> +                       goto end;
> +
> +               cpuidle_state_table[0].flags &= ~CPUIDLE_FLAG_UNUSABLE;
> +               cpuidle_state_table[1].flags |= CPUIDLE_FLAG_UNUSABLE;
> +
> +               /* Disable C1E by clearing the "C1E promotion" bit. */
> +               disable_promotion_to_c1e = true;
> +               return;
> +       }
> +end:
> +       /* Make sure C1E is enabled by default */
> +       c1e_promotion_enable();
> +}
> +
>  /**
>   * spr_idle_state_table_update - Adjust Sapphire Rapids idle states table.
>   */
> @@ -1642,6 +1775,10 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
>         case INTEL_FAM6_SAPPHIRERAPIDS_X:
>                 spr_idle_state_table_update();
>                 break;
> +       case INTEL_FAM6_ALDERLAKE:
> +       case INTEL_FAM6_ALDERLAKE_L:
> +               adl_idle_state_table_update();
> +               break;
>         }
>
>         for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) {
> --
> 2.17.1
>

      reply	other threads:[~2022-04-22 13:54 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-15  9:39 [PATCH] intel_idle: add AlderLake support Zhang Rui
2022-04-22 13:53 ` Rafael J. Wysocki [this message]

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='CAJZ5v0jEFX-iv=NagN0MxYWEOGWjP5qbgPh=PL9wg5dUKDQiaQ@mail.gmail.com' \
    --to=rafael@kernel.org \
    --cc=artem.bityutskiy@linux.intel.com \
    --cc=linux-pm@vger.kernel.org \
    --cc=rjw@rjwysocki.net \
    --cc=rui.zhang@intel.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).