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: Li Zhong <zhong@linux.vnet.ibm.com> ======================= Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
323a6bf1d6
commit
fb9125680d
2 changed files with 16 additions and 0 deletions
|
@ -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)
|
||||||
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 @@
|
||||||
#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)
|
||||||
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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue