HV: Use the mwait instead of pause for cpu_idle

Now it will use the pause when cpu is in idle state. It will consume
more power. If the mwait is supported, it will use the monitor/mwait to
enter the deep CPU C-state. It helps to save power.

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
This commit is contained in:
Zhao Yakui
2019-08-27 16:25:39 +08:00
parent 21bd1c8bd3
commit a7706e0c39
4 changed files with 49 additions and 17 deletions

View File

@@ -92,9 +92,7 @@ void default_idle(__unused struct sched_object *obj)
} else if (need_shutdown_vm(pcpu_id)) {
shutdown_vm_from_idle(pcpu_id);
} else {
CPU_IRQ_ENABLE();
cpu_do_idle();
CPU_IRQ_DISABLE();
}
}
}

View File

@@ -12,6 +12,12 @@
#include <lapic.h>
#include <schedule.h>
#include <sprintf.h>
#include <cpuid.h>
#include <cpu_caps.h>
#define CPUID_MWAIT_LEAF 5
#define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1
#define CPUID5_ECX_INTERRUPT_BREAK 0x2
static uint64_t pcpu_used_bitmap;
@@ -20,7 +26,19 @@ void init_scheduler(void)
struct sched_context *ctx;
uint32_t i;
uint16_t pcpu_nums = get_pcpu_nums();
uint32_t mwait_flag = 0;
if (has_monitor_cap()) {
uint32_t eax, ebx, ecx, edx;
mwait_flag = 1;
cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
!(ecx & CPUID5_ECX_INTERRUPT_BREAK) ||
!edx) {
mwait_flag = 0;
}
}
for (i = 0U; i < pcpu_nums; i++) {
ctx = &per_cpu(sched_ctx, i);
@@ -29,6 +47,7 @@ void init_scheduler(void)
INIT_LIST_HEAD(&ctx->runqueue);
ctx->flags = 0UL;
ctx->curr_obj = NULL;
ctx->mwait_flags = mwait_flag;
}
}