|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] x86/idle: re-arrange dead-idle handling
commit 73cb1383bf8d9712c2df4a7bc50210d5f7cf0900
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue May 21 08:30:23 2019 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue May 21 08:30:23 2019 +0200
x86/idle: re-arrange dead-idle handling
In order to be able to wake parked CPUs from default_dead_idle() (for
them to then enter a different dead-idle routine), the function should
not itself loop. Move the loop into play_dead(), and use play_dead() as
well on the AP boot error path.
Furthermore, not the least considering the comment in play_dead(),
make sure NMI raised (for now this would be a bug elsewhere, but that's
about to change) against a parked or fully offline CPU won't invoke the
actual, full-blown NMI handler.
Note however that this doesn't make #MC any safer for fully offline
CPUs.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
xen/arch/x86/domain.c | 17 ++++++++++++-----
xen/arch/x86/smpboot.c | 4 ++--
xen/include/asm-x86/cpuidle.h | 1 +
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index d2d9f2fc3c..ac960ddd40 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -100,14 +100,20 @@ void default_dead_idle(void)
*/
spec_ctrl_enter_idle(get_cpu_info());
wbinvd();
- for ( ; ; )
- halt();
+ halt();
+ spec_ctrl_exit_idle(get_cpu_info());
}
-static void play_dead(void)
+void play_dead(void)
{
+ unsigned int cpu = smp_processor_id();
+
local_irq_disable();
+ /* Change the NMI handler to a nop (see comment below). */
+ _set_gate_lower(&idt_tables[cpu][TRAP_nmi], SYS_DESC_irq_gate, 0,
+ &trap_nop);
+
/*
* NOTE: After cpu_exit_clear, per-cpu variables may no longer accessible,
* as they may be freed at any time if offline CPUs don't get parked. In
@@ -118,9 +124,10 @@ static void play_dead(void)
* Consider very carefully when adding code to *dead_idle. Most hypervisor
* subsystems are unsafe to call.
*/
- cpu_exit_clear(smp_processor_id());
+ cpu_exit_clear(cpu);
- (*dead_idle)();
+ for ( ; ; )
+ dead_idle();
}
static void idle_loop(void)
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 4f65c8d52e..274865a705 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -33,6 +33,7 @@
#include <xen/serial.h>
#include <xen/numa.h>
#include <xen/cpu.h>
+#include <asm/cpuidle.h>
#include <asm/current.h>
#include <asm/mc146818rtc.h>
#include <asm/desc.h>
@@ -209,8 +210,7 @@ static void smp_callin(void)
halt:
clear_local_APIC();
spin_debug_enable();
- cpu_exit_clear(cpu);
- (*dead_idle)();
+ play_dead();
}
/* Allow the master to continue. */
diff --git a/xen/include/asm-x86/cpuidle.h b/xen/include/asm-x86/cpuidle.h
index 08da01803f..488f708305 100644
--- a/xen/include/asm-x86/cpuidle.h
+++ b/xen/include/asm-x86/cpuidle.h
@@ -20,6 +20,7 @@ int mwait_idle_init(struct notifier_block *);
int cpuidle_init_cpu(unsigned int cpu);
void default_dead_idle(void);
void acpi_dead_idle(void);
+void play_dead(void);
void trace_exit_reason(u32 *irq_traced);
void update_idle_stats(struct acpi_processor_power *,
struct acpi_processor_cx *, uint64_t, uint64_t);
--
generated by git-patchbot for /home/xen/git/xen.git#staging
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |