diff mbox series

[v2] intel_idle: Disable C1E on Jasper Lake and Elkhart Lake

Message ID 20240820041128.102452-1-kai.heng.feng@canonical.com
State New
Headers show
Series [v2] intel_idle: Disable C1E on Jasper Lake and Elkhart Lake | expand

Commit Message

Kai-Heng Feng Aug. 20, 2024, 4:11 a.m. UTC
PCIe ethernet throughut is sub-optimal on Jasper Lake and Elkhart Lake.

The CPU can take long time to exit to C0 to handle IRQ and perform DMA
when C1E is enabled.

So adjust intel_idle to use _CST when state_table is absent, and disable
C1E on those two platforms.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=219023
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
---
v2:
 - Allow the driver to use _CST when state_table is absent.

 drivers/idle/intel_idle.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

Comments

Rafael J. Wysocki Aug. 20, 2024, 10:31 a.m. UTC | #1
On Tue, Aug 20, 2024 at 6:20 AM Kai-Heng Feng
<kai.heng.feng@canonical.com> wrote:
>
> PCIe ethernet throughut is sub-optimal on Jasper Lake and Elkhart Lake.
>
> The CPU can take long time to exit to C0 to handle IRQ and perform DMA
> when C1E is enabled.
>
> So adjust intel_idle to use _CST when state_table is absent, and disable
> C1E on those two platforms.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=219023
> Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
> ---
> v2:
>  - Allow the driver to use _CST when state_table is absent.
>
>  drivers/idle/intel_idle.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
> index 9aab7abc2ae9..ac1c6f4f9c7f 100644
> --- a/drivers/idle/intel_idle.c
> +++ b/drivers/idle/intel_idle.c
> @@ -1475,6 +1475,10 @@ static const struct idle_cpu idle_cpu_dnv __initconst = {
>         .use_acpi = true,
>  };
>
> +static const struct idle_cpu idle_cpu_tmt __initconst = {
> +       .disable_promotion_to_c1e = true,
> +};
> +
>  static const struct idle_cpu idle_cpu_snr __initconst = {
>         .state_table = snr_cstates,
>         .disable_promotion_to_c1e = true,
> @@ -1538,6 +1542,8 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
>         X86_MATCH_VFM(INTEL_ATOM_GOLDMONT,      &idle_cpu_bxt),
>         X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS, &idle_cpu_bxt),
>         X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D,    &idle_cpu_dnv),
> +       X86_MATCH_VFM(INTEL_ATOM_TREMONT,       &idle_cpu_tmt),
> +       X86_MATCH_VFM(INTEL_ATOM_TREMONT_L,     &idle_cpu_tmt),
>         X86_MATCH_VFM(INTEL_ATOM_TREMONT_D,     &idle_cpu_snr),
>         X86_MATCH_VFM(INTEL_ATOM_CRESTMONT,     &idle_cpu_grr),
>         X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X,   &idle_cpu_srf),
> @@ -2075,7 +2081,7 @@ static void __init intel_idle_cpuidle_driver_init(struct cpuidle_driver *drv)
>
>         drv->state_count = 1;
>
> -       if (icpu)
> +       if (icpu && icpu->state_table)
>                 intel_idle_init_cstates_icpu(drv);
>         else
>                 intel_idle_init_cstates_acpi(drv);
> @@ -2209,7 +2215,11 @@ static int __init intel_idle_init(void)
>
>         icpu = (const struct idle_cpu *)id->driver_data;
>         if (icpu) {
> -               cpuidle_state_table = icpu->state_table;
> +               if (icpu->state_table)
> +                       cpuidle_state_table = icpu->state_table;
> +               else if (!intel_idle_acpi_cst_extract())
> +                       return -ENODEV;
> +
>                 auto_demotion_disable_flags = icpu->auto_demotion_disable_flags;
>                 if (icpu->disable_promotion_to_c1e)
>                         c1e_promotion = C1E_PROMOTION_DISABLE;
> --

That's exactly what I wanted to do, thanks for taking care of this!

I'll queue it up for 6.12 later today.
diff mbox series

Patch

diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 9aab7abc2ae9..ac1c6f4f9c7f 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -1475,6 +1475,10 @@  static const struct idle_cpu idle_cpu_dnv __initconst = {
 	.use_acpi = true,
 };
 
+static const struct idle_cpu idle_cpu_tmt __initconst = {
+	.disable_promotion_to_c1e = true,
+};
+
 static const struct idle_cpu idle_cpu_snr __initconst = {
 	.state_table = snr_cstates,
 	.disable_promotion_to_c1e = true,
@@ -1538,6 +1542,8 @@  static const struct x86_cpu_id intel_idle_ids[] __initconst = {
 	X86_MATCH_VFM(INTEL_ATOM_GOLDMONT,	&idle_cpu_bxt),
 	X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS,	&idle_cpu_bxt),
 	X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D,	&idle_cpu_dnv),
+	X86_MATCH_VFM(INTEL_ATOM_TREMONT,       &idle_cpu_tmt),
+	X86_MATCH_VFM(INTEL_ATOM_TREMONT_L,     &idle_cpu_tmt),
 	X86_MATCH_VFM(INTEL_ATOM_TREMONT_D,	&idle_cpu_snr),
 	X86_MATCH_VFM(INTEL_ATOM_CRESTMONT,	&idle_cpu_grr),
 	X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X,	&idle_cpu_srf),
@@ -2075,7 +2081,7 @@  static void __init intel_idle_cpuidle_driver_init(struct cpuidle_driver *drv)
 
 	drv->state_count = 1;
 
-	if (icpu)
+	if (icpu && icpu->state_table)
 		intel_idle_init_cstates_icpu(drv);
 	else
 		intel_idle_init_cstates_acpi(drv);
@@ -2209,7 +2215,11 @@  static int __init intel_idle_init(void)
 
 	icpu = (const struct idle_cpu *)id->driver_data;
 	if (icpu) {
-		cpuidle_state_table = icpu->state_table;
+		if (icpu->state_table)
+			cpuidle_state_table = icpu->state_table;
+		else if (!intel_idle_acpi_cst_extract())
+			return -ENODEV;
+
 		auto_demotion_disable_flags = icpu->auto_demotion_disable_flags;
 		if (icpu->disable_promotion_to_c1e)
 			c1e_promotion = C1E_PROMOTION_DISABLE;