mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-18 19:57:31 +00:00
profiling: enable to capture dropped samples while buffering
Since the profiling utilizes the limited size of buffer to capture sample data, dropping samples could happen while collecting data if data is generated faster than flushing by consumer. Capturing the dropped sample info is critical to understand how much the data is reliable to use. To capture the information, the new hypercall "PROFILING_GET_STATUS" is introduced. Tracked-On: #2474 Signed-off-by: Manisha Chinthapally <manisha.chinthapally@intel.com> Signed-off-by: Min Lim <min.yeol.lim@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
18b04451e1
commit
ec4dd2284c
@ -51,6 +51,9 @@ static int32_t hcall_profiling_ops(struct acrn_vm *vm, uint64_t cmd, uint64_t pa
|
||||
case PROFILING_GET_PCPUID:
|
||||
ret = profiling_get_pcpu_id(vm, param);
|
||||
break;
|
||||
case PROFILING_GET_STATUS:
|
||||
ret = profiling_get_status_info(vm, param);
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: invalid profiling command %llu\n", __func__, cmd);
|
||||
ret = -1;
|
||||
|
@ -788,14 +788,6 @@ static void profiling_stop_pmu(void)
|
||||
__func__, i, per_cpu(profiling_info.sep_state, i).samples_logged,
|
||||
per_cpu(profiling_info.sep_state, i).samples_dropped);
|
||||
|
||||
per_cpu(profiling_info.sep_state, i).samples_logged = 0U;
|
||||
per_cpu(profiling_info.sep_state, i).samples_dropped = 0U;
|
||||
per_cpu(profiling_info.sep_state, i).valid_pmi_count = 0U;
|
||||
per_cpu(profiling_info.sep_state, i).total_pmi_count = 0U;
|
||||
per_cpu(profiling_info.sep_state, i).total_vmexit_count = 0U;
|
||||
per_cpu(profiling_info.sep_state, i).frozen_well = 0U;
|
||||
per_cpu(profiling_info.sep_state, i).frozen_delayed = 0U;
|
||||
per_cpu(profiling_info.sep_state, i).nofrozen_pmi = 0U;
|
||||
}
|
||||
|
||||
smp_call_function(get_active_pcpu_bitmap(), profiling_ipi_handler, NULL);
|
||||
@ -1268,6 +1260,43 @@ int32_t profiling_get_pcpu_id(struct acrn_vm *vm, uint64_t addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update collection statictics
|
||||
*/
|
||||
int32_t profiling_get_status_info(struct acrn_vm *vm, uint64_t gpa)
|
||||
{
|
||||
uint16_t i;
|
||||
uint16_t pcpu_nums = get_pcpu_nums();
|
||||
struct profiling_status pstats[pcpu_nums];
|
||||
|
||||
(void)memset((void *)&pstats, 0U, pcpu_nums*sizeof(struct profiling_status));
|
||||
|
||||
dev_dbg(ACRN_DBG_PROFILING, "%s: entering", __func__);
|
||||
|
||||
if (copy_from_gpa(vm, &pstats, gpa,
|
||||
pcpu_nums*sizeof(struct profiling_status)) != 0) {
|
||||
pr_err("%s: Unable to copy addr from vm\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0U; i < pcpu_nums; i++) {
|
||||
pstats[i].samples_logged =
|
||||
per_cpu(profiling_info.sep_state, i).samples_logged;
|
||||
pstats[i].samples_dropped =
|
||||
per_cpu(profiling_info.sep_state, i).samples_dropped;
|
||||
}
|
||||
|
||||
if (copy_to_gpa(vm, &pstats, gpa,
|
||||
pcpu_nums*sizeof(struct profiling_status)) != 0) {
|
||||
pr_err("%s: Unable to copy param to vm\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(ACRN_DBG_PROFILING, "%s: exiting", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* IPI interrupt handler function
|
||||
*/
|
||||
@ -1411,6 +1440,11 @@ void profiling_setup(void)
|
||||
per_cpu(profiling_info.sep_state, cpu).total_vmexit_count = 0U;
|
||||
per_cpu(profiling_info.sep_state, cpu).pmu_state = PMU_INITIALIZED;
|
||||
per_cpu(profiling_info.sep_state, cpu).vmexit_msr_cnt = 0;
|
||||
per_cpu(profiling_info.sep_state, cpu).samples_logged = 0U;
|
||||
per_cpu(profiling_info.sep_state, cpu).samples_dropped = 0U;
|
||||
per_cpu(profiling_info.sep_state, cpu).frozen_well = 0U;
|
||||
per_cpu(profiling_info.sep_state, cpu).frozen_delayed = 0U;
|
||||
per_cpu(profiling_info.sep_state, cpu).nofrozen_pmi = 0U;
|
||||
|
||||
msr_write(MSR_IA32_EXT_APIC_LVT_PMI,
|
||||
VECTOR_PMI | LVT_PERFCTR_BIT_MASK);
|
||||
|
@ -174,6 +174,12 @@ struct guest_vm_info {
|
||||
uint16_t guest_vm_id;
|
||||
int32_t external_vector;
|
||||
};
|
||||
|
||||
struct profiling_status {
|
||||
uint32_t samples_logged;
|
||||
uint32_t samples_dropped;
|
||||
};
|
||||
|
||||
struct sep_state {
|
||||
sep_pmu_state pmu_state;
|
||||
|
||||
@ -304,6 +310,7 @@ int32_t profiling_set_control(struct acrn_vm *vm, uint64_t addr);
|
||||
int32_t profiling_configure_pmi(struct acrn_vm *vm, uint64_t addr);
|
||||
int32_t profiling_configure_vmsw(struct acrn_vm *vm, uint64_t addr);
|
||||
void profiling_ipi_handler(void *data);
|
||||
int32_t profiling_get_status_info(struct acrn_vm *vm, uint64_t addr);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -325,7 +325,8 @@ enum profiling_cmd_type {
|
||||
PROFILING_SET_CONTROL_SWITCH,
|
||||
PROFILING_CONFIG_PMI,
|
||||
PROFILING_CONFIG_VMSWITCH,
|
||||
PROFILING_GET_PCPUID
|
||||
PROFILING_GET_PCPUID,
|
||||
PROFILING_GET_STATUS
|
||||
};
|
||||
|
||||
#endif /* ACRN_HV_DEFS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user