Index: cpu.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/cpu.c,v retrieving revision 1.152 diff -u -p -r1.152 cpu.c --- cpu.c 28 Nov 2020 18:40:01 -0000 1.152 +++ cpu.c 29 Dec 2020 12:25:15 -0000 @@ -69,6 +69,7 @@ #include "vmm.h" #include "pctr.h" #include "pvbus.h" +#include "kstat.h" #include #include @@ -113,6 +114,10 @@ #include #endif +#if NKSTAT > 0 +#include +#endif + #include #include #include @@ -686,6 +691,61 @@ replacexsave(void) splx(s); } +#if NKSTAT > 0 +struct cpu_perf_kstat { + struct kstat_kv kp_tsc; + struct kstat_kv kp_mperf; + struct kstat_kv kp_aperf; +}; + +int +cpu_perf_read(struct kstat *ks) +{ + struct cpu_perf_kstat *kp = ks->ks_data; + unsigned long s; + + s = intr_disable(); + kstat_kv_u64(&kp->kp_tsc) = rdtsc(); + kstat_kv_u64(&kp->kp_mperf) = rdmsr(0xe7); + kstat_kv_u64(&kp->kp_aperf) = rdmsr(0xe8); + intr_restore(s); + + nanouptime(&ks->ks_updated); + + return (0); +} + +void +cpu_init_kstat(struct cpu_info *ci) +{ + struct kstat *ks; + struct cpu_perf_kstat *kp; + + ks = kstat_create("cpu", CPU_INFO_UNIT(ci), "perf", 0, KSTAT_T_KV, 0); + if (ks == NULL) { + printf("%s: unable to create kstats\n", ci->ci_dev->dv_xname); + return; + } + + kstat_set_cpu(ks, ci); + + kp = malloc(sizeof(*kp), M_DEVBUF, M_WAITOK|M_ZERO); + + kstat_kv_unit_init(&kp->kp_tsc, "tsc", + KSTAT_KV_T_COUNTER64, KSTAT_KV_U_CYCLES); + kstat_kv_unit_init(&kp->kp_mperf, "mperf", + KSTAT_KV_T_COUNTER64, KSTAT_KV_U_CYCLES); + kstat_kv_unit_init(&kp->kp_aperf, "aperf", + KSTAT_KV_T_COUNTER64, KSTAT_KV_U_CYCLES); + + ks->ks_data = kp; + ks->ks_datalen = sizeof(*kp); + ks->ks_read = cpu_perf_read; + + //ci->ci_kstat = ks; + kstat_install(ks); +} +#endif /* NKSTAT > 0 */ /* * Initialize the processor appropriately. @@ -808,6 +868,10 @@ cpu_boot_secondary_processors(void) continue; if ((ci->ci_flags & CPUF_PRESENT) == 0) continue; +#if NKSTAT > 0 + /* this is a convenient place to do this */ + cpu_init_kstat(ci); +#endif if (ci->ci_flags & (CPUF_BSP | CPUF_SP | CPUF_PRIMARY)) continue; ci->ci_randseed = (arc4random() & 0x7fffffff) + 1;