1*0418f908SAnthony Harivel /* 2*0418f908SAnthony Harivel * QEMU KVM support -- x86 virtual energy-related MSR. 3*0418f908SAnthony Harivel * 4*0418f908SAnthony Harivel * Copyright 2024 Red Hat, Inc. 2024 5*0418f908SAnthony Harivel * 6*0418f908SAnthony Harivel * Author: 7*0418f908SAnthony Harivel * Anthony Harivel <aharivel@redhat.com> 8*0418f908SAnthony Harivel * 9*0418f908SAnthony Harivel * This work is licensed under the terms of the GNU GPL, version 2 or later. 10*0418f908SAnthony Harivel * See the COPYING file in the top-level directory. 11*0418f908SAnthony Harivel * 12*0418f908SAnthony Harivel */ 13*0418f908SAnthony Harivel 14*0418f908SAnthony Harivel #ifndef VMSR_ENERGY_H 15*0418f908SAnthony Harivel #define VMSR_ENERGY_H 16*0418f908SAnthony Harivel 17*0418f908SAnthony Harivel #include <stdint.h> 18*0418f908SAnthony Harivel #include "qemu/osdep.h" 19*0418f908SAnthony Harivel #include "io/channel-socket.h" 20*0418f908SAnthony Harivel #include "hw/i386/topology.h" 21*0418f908SAnthony Harivel 22*0418f908SAnthony Harivel /* 23*0418f908SAnthony Harivel * Define the interval time in micro seconds between 2 samples of 24*0418f908SAnthony Harivel * energy related MSRs 25*0418f908SAnthony Harivel */ 26*0418f908SAnthony Harivel #define MSR_ENERGY_THREAD_SLEEP_US 1000000.0 27*0418f908SAnthony Harivel 28*0418f908SAnthony Harivel /* 29*0418f908SAnthony Harivel * Thread statistic 30*0418f908SAnthony Harivel * @ thread_id: TID (thread ID) 31*0418f908SAnthony Harivel * @ is_vcpu: true if TID is vCPU thread 32*0418f908SAnthony Harivel * @ cpu_id: CPU number last executed on 33*0418f908SAnthony Harivel * @ pkg_id: package number of the CPU 34*0418f908SAnthony Harivel * @ vcpu_id: vCPU ID 35*0418f908SAnthony Harivel * @ vpkg: virtual package number 36*0418f908SAnthony Harivel * @ acpi_id: APIC id of the vCPU 37*0418f908SAnthony Harivel * @ utime: amount of clock ticks the thread 38*0418f908SAnthony Harivel * has been scheduled in User mode 39*0418f908SAnthony Harivel * @ stime: amount of clock ticks the thread 40*0418f908SAnthony Harivel * has been scheduled in System mode 41*0418f908SAnthony Harivel * @ delta_ticks: delta of utime+stime between 42*0418f908SAnthony Harivel * the two samples (before/after sleep) 43*0418f908SAnthony Harivel */ 44*0418f908SAnthony Harivel struct vmsr_thread_stat { 45*0418f908SAnthony Harivel unsigned int thread_id; 46*0418f908SAnthony Harivel bool is_vcpu; 47*0418f908SAnthony Harivel unsigned int cpu_id; 48*0418f908SAnthony Harivel unsigned int pkg_id; 49*0418f908SAnthony Harivel unsigned int vpkg_id; 50*0418f908SAnthony Harivel unsigned int vcpu_id; 51*0418f908SAnthony Harivel unsigned long acpi_id; 52*0418f908SAnthony Harivel unsigned long long *utime; 53*0418f908SAnthony Harivel unsigned long long *stime; 54*0418f908SAnthony Harivel unsigned long long delta_ticks; 55*0418f908SAnthony Harivel }; 56*0418f908SAnthony Harivel 57*0418f908SAnthony Harivel /* 58*0418f908SAnthony Harivel * Package statistic 59*0418f908SAnthony Harivel * @ e_start: package energy counter before the sleep 60*0418f908SAnthony Harivel * @ e_end: package energy counter after the sleep 61*0418f908SAnthony Harivel * @ e_delta: delta of package energy counter 62*0418f908SAnthony Harivel * @ e_ratio: store the energy ratio of non-vCPU thread 63*0418f908SAnthony Harivel * @ nb_vcpu: number of vCPU running on this package 64*0418f908SAnthony Harivel */ 65*0418f908SAnthony Harivel struct vmsr_package_energy_stat { 66*0418f908SAnthony Harivel uint64_t e_start; 67*0418f908SAnthony Harivel uint64_t e_end; 68*0418f908SAnthony Harivel uint64_t e_delta; 69*0418f908SAnthony Harivel uint64_t e_ratio; 70*0418f908SAnthony Harivel unsigned int nb_vcpu; 71*0418f908SAnthony Harivel }; 72*0418f908SAnthony Harivel 73*0418f908SAnthony Harivel typedef struct vmsr_thread_stat vmsr_thread_stat; 74*0418f908SAnthony Harivel typedef struct vmsr_package_energy_stat vmsr_package_energy_stat; 75*0418f908SAnthony Harivel 76*0418f908SAnthony Harivel char *vmsr_compute_default_paths(void); 77*0418f908SAnthony Harivel void vmsr_read_thread_stat(pid_t pid, 78*0418f908SAnthony Harivel unsigned int thread_id, 79*0418f908SAnthony Harivel unsigned long long *utime, 80*0418f908SAnthony Harivel unsigned long long *stime, 81*0418f908SAnthony Harivel unsigned int *cpu_id); 82*0418f908SAnthony Harivel 83*0418f908SAnthony Harivel QIOChannelSocket *vmsr_open_socket(const char *path); 84*0418f908SAnthony Harivel uint64_t vmsr_read_msr(uint32_t reg, uint32_t cpu_id, 85*0418f908SAnthony Harivel uint32_t tid, QIOChannelSocket *sioc); 86*0418f908SAnthony Harivel void vmsr_delta_ticks(vmsr_thread_stat *thd_stat, int i); 87*0418f908SAnthony Harivel unsigned int vmsr_get_maxcpus(void); 88*0418f908SAnthony Harivel unsigned int vmsr_get_max_physical_package(unsigned int max_cpus); 89*0418f908SAnthony Harivel unsigned int vmsr_count_cpus_per_package(unsigned int *package_count, 90*0418f908SAnthony Harivel unsigned int max_pkgs); 91*0418f908SAnthony Harivel int vmsr_get_physical_package_id(int cpu_id); 92*0418f908SAnthony Harivel pid_t *vmsr_get_thread_ids(pid_t pid, unsigned int *num_threads); 93*0418f908SAnthony Harivel double vmsr_get_ratio(uint64_t e_delta, 94*0418f908SAnthony Harivel unsigned long long delta_ticks, 95*0418f908SAnthony Harivel unsigned int maxticks); 96*0418f908SAnthony Harivel void vmsr_init_topo_info(X86CPUTopoInfo *topo_info, const MachineState *ms); 97*0418f908SAnthony Harivel bool is_host_cpu_intel(void); 98*0418f908SAnthony Harivel int is_rapl_enabled(void); 99*0418f908SAnthony Harivel #endif /* VMSR_ENERGY_H */ 100