提交 fb912568 编写于 作者: L Li Zhong 提交者: Benjamin Herrenschmidt

powerpc: Fix a lazy irq related WARING in arch_local_irq_restore()

The pseries CPU hotplug code uses cede_processor without properly
synchronizing the SW and HW interrupt enable state. This fixes
it using the same helpers that were written for the idle code.
Signed-off-by: NLi Zhong <zhong@linux.vnet.ibm.com>

=======================
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
上级 323a6bf1
...@@ -127,9 +127,16 @@ static void pseries_mach_cpu_die(void) ...@@ -127,9 +127,16 @@ static void pseries_mach_cpu_die(void)
get_lppaca()->donate_dedicated_cpu = 1; get_lppaca()->donate_dedicated_cpu = 1;
while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
while (!prep_irq_for_idle()) {
local_irq_enable();
local_irq_disable();
}
extended_cede_processor(cede_latency_hint); extended_cede_processor(cede_latency_hint);
} }
local_irq_disable();
if (!get_lppaca()->shared_proc) if (!get_lppaca()->shared_proc)
get_lppaca()->donate_dedicated_cpu = 0; get_lppaca()->donate_dedicated_cpu = 0;
get_lppaca()->idle = 0; get_lppaca()->idle = 0;
...@@ -137,6 +144,7 @@ static void pseries_mach_cpu_die(void) ...@@ -137,6 +144,7 @@ static void pseries_mach_cpu_die(void)
if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) { if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
unregister_slb_shadow(hwcpu); unregister_slb_shadow(hwcpu);
hard_irq_disable();
/* /*
* Call to start_secondary_resume() will not return. * Call to start_secondary_resume() will not return.
* Kernel stack will be reset and start_secondary() * Kernel stack will be reset and start_secondary()
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define _PSERIES_PLPAR_WRAPPERS_H #define _PSERIES_PLPAR_WRAPPERS_H
#include <linux/string.h> #include <linux/string.h>
#include <linux/irqflags.h>
#include <asm/hvcall.h> #include <asm/hvcall.h>
#include <asm/paca.h> #include <asm/paca.h>
...@@ -41,7 +42,14 @@ static inline long extended_cede_processor(unsigned long latency_hint) ...@@ -41,7 +42,14 @@ static inline long extended_cede_processor(unsigned long latency_hint)
u8 old_latency_hint = get_cede_latency_hint(); u8 old_latency_hint = get_cede_latency_hint();
set_cede_latency_hint(latency_hint); set_cede_latency_hint(latency_hint);
rc = cede_processor(); rc = cede_processor();
#ifdef CONFIG_TRACE_IRQFLAGS
/* Ensure that H_CEDE returns with IRQs on */
if (WARN_ON(!(mfmsr() & MSR_EE)))
__hard_irq_enable();
#endif
set_cede_latency_hint(old_latency_hint); set_cede_latency_hint(old_latency_hint);
return rc; return rc;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册