Re: [PATCH 04/36] cpuidle,intel_idle: Fix CPUIDLE_FLAG_IRQ_ENABLE
From: "Rafael J. Wysocki" <rafael@kernel.org>
Date: 2022-06-08 15:11:12
Also in:
linux-acpi, linux-alpha, linux-arch, linux-arm-msm, linux-clk, linux-m68k, linux-mips, linux-omap, linux-perf-users, linux-pm, linux-riscv, linux-s390, linux-sh, linux-tegra, linux-um, lkml, rcu, sparclinux, virtualization, xen-devel
ieu.desnoyers@efficios.com>, Frederic Weisbecker [off-list ref], Len Brown [off-list ref], linux-xtensa@linux-xtensa.org, Sascha Hauer [off-list ref], Vasily Gorbik [off-list ref], linux-arm-msm [off-list ref], linux-alpha@vger.kernel.org, linux-m68k [off-list ref], Stafford Horne [off-list ref], Linux ARM [off-list ref], chris@zankel.net, Stephen Boyd [off-list ref], dinguyen@kernel.org, Daniel Bristot de Oliveira [off-list ref], Alexander Shishkin [off-list ref], lpieralisi@kernel.org, Rasmus Villemoes [off-list ref], Joel Fernandes [off-list ref], Will Deacon [off-list ref], Boris Ostrovsky [off-list ref], Kevin Hilman [off-list ref], linux-csky@vger.kernel.org, pv-drivers@vmware.com, linux-snps-arc@lists.infradead.org, Mel Gorman [off-list ref], Jacob Pan [off-list ref], Arnd Bergmann <arnd@arndb.d e>, ulli.kroll@googlemail.com, vgupta@kernel.org, linux-clk [off-list ref], Josh Triplett [off-list ref], Steven Rostedt [off-list ref], rcu@vger.kernel.org, Borislav Petkov [off-list ref], bcain@quicinc.com, Thomas Bogendoerfer [off-list ref], Parisc List [off-list ref], Sudeep Holla [off-list ref], Shawn Guo [off-list ref], David Miller [off-list ref], Rich Felker [off-list ref], Tony Lindgren [off-list ref], amakhalov@vmware.com, Bjorn Andersson [off-list ref], "H. Peter Anvin" [off-list ref], sparclinux@vger.kernel.org, linux-hexagon@vger.kernel.org, linux-riscv [off-list ref], anton.ivanov@cambridgegreys.com, jonas@southpole.se, Yury Norov [off-list ref], Richard Weinberger [off-list ref], the arch/x86 maintainers [off-list ref], Russell King - ARM Linux [off-list ref], Ingo Molnar [off-list ref], Albert Ou [off-list ref], "P aul E. McKenney" [off-list ref], Heiko Carstens [off-list ref], stefan.kristiansson@saunalahti.fi, openrisc@lists.librecores.org, Paul Walmsley [off-list ref], linux-tegra [off-list ref], namhyung@kernel.org, Andy Shevchenko [off-list ref], jpoimboe@kernel.org, Juergen Gross [off-list ref], Michal Simek [off-list ref], "open list:BROADCOM NVRAM DRIVER" [off-list ref], Palmer Dabbelt [off-list ref], Anup Patel [off-list ref], ink@jurassic.park.msu.ru, Johannes Berg [off-list ref], linuxppc-dev [off-list ref] Errors-To: linuxppc-dev-bounces+linuxppc-dev=archiver.kernel.org@lists.ozlabs.org Sender: "Linuxppc-dev" [off-list ref] On Wed, Jun 8, 2022 at 4:47 PM Peter Zijlstra [off-list ref] wrote:
Commit c227233ad64c ("intel_idle: enable interrupts before C1 on
Xeons") wrecked intel_idle in two ways:
- must not have tracing in idle functions
- must return with IRQs disabled
Additionally, it added a branch for no good reason.
Fixes: c227233ad64c ("intel_idle: enable interrupts before C1 on Xeons")
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>Acked-by: Rafael J. Wysocki <redacted> And do I think correctly that this can be applied without the rest of the series?
quoted hunk ↗ jump to hunk
--- drivers/idle/intel_idle.c | 48 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-)--- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c@@ -129,21 +137,37 @@ static unsigned int mwait_substates __in * * Must be called under local_irq_disable(). */ + -static __cpuidle int intel_idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index) +static __always_inline int __intel_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) { struct cpuidle_state *state = &drv->states[index]; unsigned long eax = flg2MWAIT(state->flags); unsigned long ecx = 1; /* break on interrupt flag */ - if (state->flags & CPUIDLE_FLAG_IRQ_ENABLE) - local_irq_enable(); - mwait_idle_with_hints(eax, ecx); return index; } +static __cpuidle int intel_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + return __intel_idle(dev, drv, index); +} + +static __cpuidle int intel_idle_irq(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + int ret; + + raw_local_irq_enable(); + ret = __intel_idle(dev, drv, index); + raw_local_irq_disable(); + + return ret; +} + /** * intel_idle_s2idle - Ask the processor to enter the given idle state. * @dev: cpuidle device of the target CPU.@@ -1801,6 +1824,9 @@ static void __init intel_idle_init_cstat /* Structure copy. */ drv->states[drv->state_count] = cpuidle_state_table[cstate]; + if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IRQ_ENABLE) + drv->states[drv->state_count].enter = intel_idle_irq; + if ((disabled_states_mask & BIT(drv->state_count)) || ((icpu->use_acpi || force_use_acpi) && intel_idle_off_by_default(mwait_hint) &&