mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-12-24 06:02:32 +00:00
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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user