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 |
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 --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;
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(-)