sample vmexit data per-pCPU and per-vCPU

this feature is used to sample vmexit data as per physical CPU
and per virutal CPU of VM, command used in HV console as following:
  1. vmexit clear --> to clear current vmexit buffer
  2. vmexit -->output current vmexit info

also it gives the reschedule data as per-pcpu.

Tracked-On: #5232
Signed-off-by: Minggui Cao <minggui.cao@intel.com>
This commit is contained in:
Minggui Cao
2020-08-06 11:19:09 +08:00
committed by wenlingz
parent 978f899029
commit ea2650918b
8 changed files with 548 additions and 1 deletions

View File

@@ -17,6 +17,9 @@
void vcpu_thread(struct thread_object *obj)
{
#ifdef HV_DEBUG
uint64_t vmexit_begin = 0UL, vmexit_end = 0UL;
#endif
struct acrn_vcpu *vcpu = container_of(obj, struct acrn_vcpu, thread_obj);
uint32_t basic_exit_reason = 0U;
int32_t ret = 0;
@@ -43,6 +46,35 @@ void vcpu_thread(struct thread_object *obj)
reset_event(&vcpu->events[VCPU_EVENT_VIRTUAL_INTERRUPT]);
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 (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;
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 > vcpu->vmexit_time[basic_exit_reason][1]) {
vcpu->vmexit_time[basic_exit_reason][1] = us;
}
}
#endif
TRACE_2L(TRACE_VM_ENTER, 0UL, 0UL);
ret = run_vcpu(vcpu);
if (ret != 0) {
@@ -54,6 +86,11 @@ void vcpu_thread(struct thread_object *obj)
basic_exit_reason = vcpu->arch.exit_reason & 0xFFFFU;
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]++;
#endif
vcpu->arch.nrexits++;
profiling_pre_vmexit_handler(vcpu);

View File

@@ -163,6 +163,10 @@ void schedule(void)
struct thread_object *prev = ctl->curr_obj;
uint64_t rflag;
#ifdef HV_DEBUG
get_cpu_var(resched_times)++;
#endif
obtain_schedule_lock(pcpu_id, &rflag);
if (ctl->scheduler->pick_next != NULL) {
next = ctl->scheduler->pick_next(ctl);