arch/x86_64: Add ARCH_X86_64_IDLE_NOP and ARCH_X86_64_IDLE_MWAIT

Using the HLT instruction in VM usually traps into the Hypervisor and releases CPU control. This will result in real-time performance degradation. Using the NOP or MWAIT instruction for an IDLE loop can reduce energy consumption while not trapping into the Hypervisor.

Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
This commit is contained in:
ouyangxiangzhen 2024-06-17 18:31:06 +08:00 committed by Mateusz Szafoni
parent fba0324bd7
commit 74df0974b2
2 changed files with 51 additions and 1 deletions

View File

@ -35,6 +35,38 @@ config ARCH_X86_64_ACPI_BIOS
endif # ARCH_X86_64_ACPI
choice
prompt "x86_64 Idle Loop Options"
default ARCH_X86_64_IDLE_DEFAULT
config ARCH_X86_64_IDLE_DEFAULT
bool "Idle Loop - HLT"
---help---
Use HLT instruction in IDLE loop.
config ARCH_X86_64_IDLE_NOP
bool "Idle Loop - NOP"
---help---
Use NOP instruction in IDLE loop.
This can prevent VM exit in some virtualized environments,
thereby improving real-time performance.
config ARCH_X86_64_IDLE_MWAIT
bool "Idle Loop - MWAIT"
---help---
Use MONITOR/MWAIT instruction in IDLE loop.
endchoice # x86_64 Idle Loop Options
config ARCH_X86_64_IDLE_MWAIT_ECX
hex "Idle MWAIT ECX value"
default 0x0
range 0x0 0xF
depends on ARCH_X86_64_IDLE_MWAIT
---help---
MWAIT ECX indicates the C-States
(0x0 for C1, 0x1 for C1E and so on).
config ARCH_X86_64_HAVE_XSAVE
bool "XSAVE support"
default y

View File

@ -64,7 +64,25 @@ void up_idle(void)
* "fake" timer interrupts. Hopefully, something will wake up.
*/
sched_process_timer();
nxsched_process_timer();
#elif defined(CONFIG_ARCH_X86_64_IDLE_NOP)
asm volatile("nop");
#elif defined(CONFIG_ARCH_X86_64_IDLE_MWAIT_ECX)
/* Dummy value to make MONITOR/MWAIT work */
int dummy;
/* MONITOR eax, ecx, edx */
asm volatile(".byte 0x0f, 0x01, 0xc8" ::
"a"(&dummy), "c"(0), "d"(0));
/* We enable sub C-state here and wait for interrupts */
/* MWAIT eax, ecx */
asm volatile(".byte 0x0f, 0x01, 0xc9" ::
"a"(0), "c"(CONFIG_ARCH_X86_64_IDLE_MWAIT_ECX));
#else
__asm__ volatile("hlt");
#endif