From: chenjiajun chenjiajun8@huawei.com
virt inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I919BF CVE: NA
-------------------------------------
This patch export cpu time related items to vcpu_stat. Contain: steal, st_max, utime, stime, gtime
The definitions of these items are: steal: cpu time VCPU waits for PCPU while it is servicing another VCPU st_max: max scheduling delay utime: cpu time in userspace stime: cpu time in sys gtime: cpu time in guest
Through these items, user can get many cpu usage info of vcpu, such as: CPU Usage of Guest = gtime_delta / delta_cputime CPU Usage of Hyp = (utime_delta - gtime_delta + stime_delta) / delta_cputime CPU Usage of Steal = steal_delta / delta_cputime Max Scheduling Delay = st_max
Signed-off-by: liangpeng liangpeng10@huawei.com Signed-off-by: chenjiajun chenjiajun8@huawei.com Signed-off-by: liangtian liangtian13@huawei.com --- arch/arm64/include/asm/kvm_host.h | 5 +++++ arch/arm64/kvm/arm.c | 31 +++++++++++++++++++++++++++++++ arch/arm64/kvm/guest.c | 5 +++++ include/linux/kvm_host.h | 4 ++++ virt/kvm/kvm_main.c | 1 + 5 files changed, 46 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 606ab46be948..6991437c11bc 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -921,6 +921,11 @@ struct kvm_vcpu_stat { u64 smc_exit_stat; u64 sve_exit_stat; u64 debug_exit_stat; + u64 steal; + u64 st_max; + u64 utime; + u64 stime; + u64 gtime; };
unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 4866b3f7b4ea..446c0bd2c359 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -421,6 +421,22 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
}
+#ifdef CONFIG_ARCH_VCPU_STAT +void kvm_arch_vcpu_stat_reset(struct kvm_vcpu_stat *vcpu_stat) +{ + vcpu_stat->st_max = 0; +} + +static void update_steal_time(struct kvm_vcpu *vcpu) +{ + u64 delta; + + delta = current->sched_info.run_delay - vcpu->stat.steal; + vcpu->stat.steal = current->sched_info.run_delay; + vcpu->stat.st_max = max(vcpu->stat.st_max, delta); +} +#endif + void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { struct kvm_s2_mmu *mmu; @@ -459,6 +475,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) else vcpu_set_wfx_traps(vcpu);
+#ifdef CONFIG_ARCH_VCPU_STAT + update_steal_time(vcpu); +#endif if (vcpu_has_ptrauth(vcpu)) vcpu_ptrauth_disable(vcpu); kvm_arch_vcpu_load_debug_state_flags(vcpu); @@ -828,6 +847,15 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu *vcpu) return !kvm_supports_32bit_el0(); }
+#ifdef CONFIG_ARCH_VCPU_STAT +static void update_vcpu_stat_time(struct kvm_vcpu_stat *vcpu_stat) +{ + vcpu_stat->utime = current->utime; + vcpu_stat->stime = current->stime; + vcpu_stat->gtime = current->gtime; +} +#endif + /** * kvm_vcpu_exit_request - returns true if the VCPU should *not* enter the guest * @vcpu: The VCPU pointer @@ -1070,6 +1098,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) }
ret = handle_exit(vcpu, ret); +#ifdef CONFIG_ARCH_VCPU_STAT + update_vcpu_stat_time(&vcpu->stat); +#endif }
/* Tell userspace about in-kernel device output levels */ diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 7b2048f88de1..89e33337ade9 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -55,6 +55,11 @@ struct dfx_kvm_stats_debugfs_item dfx_debugfs_entries[] = { DFX_STAT("smc_exit_stat", smc_exit_stat), DFX_STAT("sve_exit_stat", sve_exit_stat), DFX_STAT("debug_exit_stat", debug_exit_stat), + DFX_STAT("steal", steal), + DFX_STAT("st_max", st_max), + DFX_STAT("utime", utime), + DFX_STAT("stime", stime), + DFX_STAT("gtime", gtime), { NULL } }; #endif diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f4779f1b90fa..328ec923c657 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2321,6 +2321,10 @@ static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu) } #endif /* CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE */
+#ifdef CONFIG_ARCH_VCPU_STAT +void kvm_arch_vcpu_stat_reset(struct kvm_vcpu_stat *vcpu_stat); +#endif + typedef int (*kvm_vm_thread_fn_t)(struct kvm *kvm, uintptr_t data);
int kvm_vm_create_worker_thread(struct kvm *kvm, kvm_vm_thread_fn_t thread_fn, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index fc6c7ad11c9c..ce76c43d88e7 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -5914,6 +5914,7 @@ static int __dfx_vcpu_stats_get(struct seq_file *p, void *v) break; memcpy(vcpu_stats + index, &vcpu->stat, sizeof(struct kvm_vcpu_stat)); + kvm_arch_vcpu_stat_reset(&vcpu->stat); ++index; } mutex_unlock(&kvm_lock);