diff --git a/hypervisor/common/hv_main.c b/hypervisor/common/hv_main.c index 8ff5aaea9..b236073d6 100644 --- a/hypervisor/common/hv_main.c +++ b/hypervisor/common/hv_main.c @@ -14,6 +14,7 @@ #include #include #include +#include void vcpu_thread(struct thread_object *obj) { @@ -47,31 +48,33 @@ void vcpu_thread(struct thread_object *obj) profiling_vmenter_handler(vcpu); #ifdef HV_DEBUG - vmexit_end = rdtsc(); - if (vmexit_begin != 0UL) { - uint64_t delta = vmexit_end - vmexit_begin; - uint32_t us = (uint32_t)ticks_to_us(delta); - uint16_t fls = (uint16_t)(fls32(us) + 1); /* to avoid us = 0 case, then fls=0xFFFF */ - uint16_t index = 0; + if (is_vmexit_sample_enabled()) { + vmexit_end = rdtsc(); + if (vmexit_begin != 0UL) { + uint64_t delta = vmexit_end - vmexit_begin; + uint32_t us = (uint32_t)ticks_to_us(delta); + uint16_t fls = (uint16_t)(fls32(us) + 1); /* to avoid us = 0 case, then fls=0xFFFF */ + uint16_t index = 0; - if (fls >= MAX_VMEXIT_LEVEL) { - index = MAX_VMEXIT_LEVEL - 1; - } else if (fls > 0) { //if fls == 0, it means the us = 0 - index = fls - 1; - } + if (fls >= MAX_VMEXIT_LEVEL) { + index = MAX_VMEXIT_LEVEL - 1; + } else if (fls > 0) { //if fls == 0, it means the us = 0 + index = fls - 1; + } - get_cpu_var(vmexit_cnt)[basic_exit_reason][index]++; - get_cpu_var(vmexit_time)[basic_exit_reason][0] += delta; + get_cpu_var(vmexit_cnt)[basic_exit_reason][index]++; + get_cpu_var(vmexit_time)[basic_exit_reason][0] += delta; - vcpu->vmexit_cnt[basic_exit_reason][index]++; - vcpu->vmexit_time[basic_exit_reason][0] += delta; + vcpu->vmexit_cnt[basic_exit_reason][index]++; + vcpu->vmexit_time[basic_exit_reason][0] += delta; - if (us > get_cpu_var(vmexit_time)[basic_exit_reason][1]) { - get_cpu_var(vmexit_time)[basic_exit_reason][1] = us; - } + if (us > get_cpu_var(vmexit_time)[basic_exit_reason][1]) { + get_cpu_var(vmexit_time)[basic_exit_reason][1] = us; + } - if (us > vcpu->vmexit_time[basic_exit_reason][1]) { - vcpu->vmexit_time[basic_exit_reason][1] = us; + if (us > vcpu->vmexit_time[basic_exit_reason][1]) { + vcpu->vmexit_time[basic_exit_reason][1] = us; + } } } #endif @@ -87,9 +90,11 @@ void vcpu_thread(struct thread_object *obj) TRACE_2L(TRACE_VM_EXIT, basic_exit_reason, vcpu_get_rip(vcpu)); #ifdef HV_DEBUG - vmexit_begin = rdtsc(); - get_cpu_var(vmexit_cnt)[basic_exit_reason][TOTAL_ARRAY_LEVEL - 1]++; - vcpu->vmexit_cnt[basic_exit_reason][TOTAL_ARRAY_LEVEL - 1]++; + if (is_vmexit_sample_enabled()) { + vmexit_begin = rdtsc(); + get_cpu_var(vmexit_cnt)[basic_exit_reason][TOTAL_ARRAY_LEVEL - 1]++; + vcpu->vmexit_cnt[basic_exit_reason][TOTAL_ARRAY_LEVEL - 1]++; + } #endif vcpu->arch.nrexits++; diff --git a/hypervisor/debug/dbg_cmd.c b/hypervisor/debug/dbg_cmd.c index f37e512d9..df14201f7 100644 --- a/hypervisor/debug/dbg_cmd.c +++ b/hypervisor/debug/dbg_cmd.c @@ -10,6 +10,7 @@ #include #include #include +#include #define MAX_PORT 0x10000 /* port 0 - 64K */ #define DEFAULT_UART_PORT 0x3F8 @@ -20,6 +21,7 @@ static const char * const cmd_list[] = { "uart=disabled", /* to disable uart */ "uart=port@", /* like uart=port@0x3F8 */ "uart=bdf@", /*like: uart=bdf@0:18.2, it is for ttyS2 */ + "vmexit=enable" }; enum IDX_CMD_DBG { @@ -27,6 +29,7 @@ enum IDX_CMD_DBG { IDX_PORT_UART, IDX_PCI_UART, + IDX_SET_VMEXIT, IDX_MAX_CMD, }; @@ -104,6 +107,9 @@ bool handle_dbg_cmd(const char *cmd, int32_t len) } else if (i == IDX_PCI_UART) { uart16550_set_property(true, false, (uint64_t)(cmd+tmp)); + } else if (i == IDX_SET_VMEXIT) { + + set_vmexit_sample_flag(true); } else { /* No other state currently, do nothing */ } diff --git a/hypervisor/debug/shell.c b/hypervisor/debug/shell.c index 0ea36d89f..c0da0c8e0 100644 --- a/hypervisor/debug/shell.c +++ b/hypervisor/debug/shell.c @@ -1913,12 +1913,19 @@ static void clear_vmexit_info_buffer(void) } +/* used to control sample vmexit data */ +static bool vmexit_sample_flag = false; + static int shell_show_vmexit_profile(__unused int argc, __unused char **argv) { if ((argc == 2) && (strcmp(argv[1], "clear") == 0)) { clear_vmexit_info_buffer(); } + if (!vmexit_sample_flag) { + printf("not enable to sample vmexit data!"); + } + get_vmexit_profile_per_pcpu(shell_log_buf, SHELL_LOG_BUF_SIZE); shell_puts(shell_log_buf); @@ -1933,3 +1940,13 @@ static int shell_show_vmexit_profile(__unused int argc, __unused char **argv) return 0; } + +void set_vmexit_sample_flag(bool to_enable) +{ + vmexit_sample_flag = to_enable; +} + +bool is_vmexit_sample_enabled(void) +{ + return vmexit_sample_flag; +} diff --git a/hypervisor/include/debug/shell.h b/hypervisor/include/debug/shell.h index 67e5f4623..3534e4e83 100644 --- a/hypervisor/include/debug/shell.h +++ b/hypervisor/include/debug/shell.h @@ -10,4 +10,7 @@ void shell_init(void); void shell_kick(void); +void set_vmexit_sample_flag(bool to_enable); +bool is_vmexit_sample_enabled(void); + #endif /* SHELL_H */