Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'turbostat-2025.06.08' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux

Pull turbostat updates from Len Brown:

- Add initial DMR support, which required smarter RAPL probe

- Fix AMD MSR RAPL energy reporting

- Add RAPL power limit configuration output

- Minor fixes

* tag 'turbostat-2025.06.08' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux:
tools/power turbostat: version 2025.06.08
tools/power turbostat: Add initial support for BartlettLake
tools/power turbostat: Add initial support for DMR
tools/power turbostat: Dump RAPL sysfs info
tools/power turbostat: Avoid probing the same perf counters
tools/power turbostat: Allow probing RAPL with platform_features->rapl_msrs cleared
tools/power turbostat: Clean up add perf/msr counter logic
tools/power turbostat: Introduce add_msr_counter()
tools/power turbostat: Remove add_msr_perf_counter_()
tools/power turbostat: Remove add_cstate_perf_counter_()
tools/power turbostat: Remove add_rapl_perf_counter_()
tools/power turbostat: Quit early for unsupported RAPL counters
tools/power turbostat: Always check rapl_joules flag
tools/power turbostat: Fix AMD package-energy reporting
tools/power turbostat: Fix RAPL_GFX_ALL typo
tools/power turbostat: Add Android support for MSR device handling
tools/power turbostat.8: pm_domain wording fix
tools/power turbostat.8: fix typo: idle_pct should be pct_idle

+363 -109
+3 -3
tools/power/x86/turbostat/turbostat.8
··· 100 100 .PP 101 101 \fB--show column\fP show only the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names. 102 102 .PP 103 - \fB--show CATEGORY --hide CATEGORY\fP Show and hide also accept a single CATEGORY of columns: "all", "topology", "idle", "frequency", "power", "cpuidle", "hwidle", "swidle", "other". "idle" (enabled by default), includes "hwidle" and "idle_pct". "cpuidle" (default disabled) includes cpuidle software invocation counters. "swidle" includes "cpuidle" plus "idle_pct". "hwidle" includes only hardware based idle residency counters. Older versions of turbostat used the term "sysfs" for what is now "swidle". 103 + \fB--show CATEGORY --hide CATEGORY\fP Show and hide also accept a single CATEGORY of columns: "all", "topology", "idle", "frequency", "power", "cpuidle", "hwidle", "swidle", "other". "idle" (enabled by default), includes "hwidle" and "pct_idle". "cpuidle" (default disabled) includes cpuidle software invocation counters. "swidle" includes "cpuidle" plus "pct_idle". "hwidle" includes only hardware based idle residency counters. Older versions of turbostat used the term "sysfs" for what is now "swidle". 104 104 .PP 105 105 \fB--Dump\fP displays the raw counter values. 106 106 .PP ··· 204 204 .PP 205 205 \fBUncMHz\fP per-package uncore MHz, instantaneous sample. 206 206 .PP 207 - \fBUMHz1.0\fP per-package uncore MHz for domain=1 and fabric_cluster=0, instantaneous sample. System summary is the average of all packages. 208 - Intel Granite Rapids systems use domains 0-2 for CPUs, and 3-4 for IO, with cluster always 0. 207 + \fBUMHz1.0\fP per-package uncore MHz for pm_domain=1 and fabric_cluster=0, instantaneous sample. System summary is the average of all packages. 208 + Intel Granite Rapids systems use pm_domains 0-2 for CPUs, and 3-4 for IO, with cluster always 0. 209 209 For the "--show" and "--hide" options, use "UncMHz" to operate on all UMHz*.* as a group. 210 210 .SH TOO MUCH INFORMATION EXAMPLE 211 211 By default, turbostat dumps all possible information -- a system configuration header, followed by columns for all counters.
+360 -106
tools/power/x86/turbostat/turbostat.c
··· 280 280 #define BIC_GROUP_FREQUENCY (BIC_Avg_MHz | BIC_Busy | BIC_Bzy_MHz | BIC_TSC_MHz | BIC_GFXMHz | BIC_GFXACTMHz | BIC_SAMMHz | BIC_SAMACTMHz | BIC_UNCORE_MHZ) 281 281 #define BIC_GROUP_HW_IDLE (BIC_Busy | BIC_CPU_c1 | BIC_CPU_c3 | BIC_CPU_c6 | BIC_CPU_c7 | BIC_GFX_rc6 | BIC_Pkgpc2 | BIC_Pkgpc3 | BIC_Pkgpc6 | BIC_Pkgpc7 | BIC_Pkgpc8 | BIC_Pkgpc9 | BIC_Pkgpc10 | BIC_CPU_LPI | BIC_SYS_LPI | BIC_Mod_c6 | BIC_Totl_c0 | BIC_Any_c0 | BIC_GFX_c0 | BIC_CPUGFX | BIC_SAM_mc6 | BIC_Diec6) 282 282 #define BIC_GROUP_SW_IDLE (BIC_Busy | BIC_cpuidle | BIC_pct_idle ) 283 - #define BIC_GROUP_IDLE (BIC_GROUP_HW_IDLE | BIC_pct_idle) 283 + #define BIC_GROUP_IDLE (BIC_GROUP_HW_IDLE | BIC_pct_idle) 284 284 #define BIC_OTHER (BIC_IRQ | BIC_NMI | BIC_SMI | BIC_ThreadC | BIC_CoreTmp | BIC_IPC) 285 285 286 286 #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC | BIC_cpuidle) ··· 539 539 #define RAPL_PKG_ALL (RAPL_PKG | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO) 540 540 #define RAPL_DRAM_ALL (RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_DRAM_POWER_INFO) 541 541 #define RAPL_CORE_ALL (RAPL_CORE | RAPL_CORE_POLICY) 542 - #define RAPL_GFX_ALL (RAPL_GFX | RAPL_GFX_POLIGY) 542 + #define RAPL_GFX_ALL (RAPL_GFX | RAPL_GFX_POLICY) 543 543 544 544 #define RAPL_AMD_F17H (RAPL_AMD_PWR_UNIT | RAPL_AMD_CORE_ENERGY_STAT | RAPL_AMD_PKG_ENERGY_STAT) 545 545 ··· 839 839 .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS, 840 840 }; 841 841 842 + static const struct platform_features dmr_features = { 843 + .has_msr_misc_feature_control = spr_features.has_msr_misc_feature_control, 844 + .has_msr_misc_pwr_mgmt = spr_features.has_msr_misc_pwr_mgmt, 845 + .has_nhm_msrs = spr_features.has_nhm_msrs, 846 + .has_config_tdp = spr_features.has_config_tdp, 847 + .bclk_freq = spr_features.bclk_freq, 848 + .supported_cstates = spr_features.supported_cstates, 849 + .cst_limit = spr_features.cst_limit, 850 + .has_msr_core_c1_res = spr_features.has_msr_core_c1_res, 851 + .has_msr_module_c6_res_ms = 1, /* DMR has Dual Core Module and MC6 MSR */ 852 + .has_irtl_msrs = spr_features.has_irtl_msrs, 853 + .has_cst_prewake_bit = spr_features.has_cst_prewake_bit, 854 + .has_fixed_rapl_psys_unit = spr_features.has_fixed_rapl_psys_unit, 855 + .trl_msrs = spr_features.trl_msrs, 856 + .rapl_msrs = 0, /* DMR does not have RAPL MSRs */ 857 + }; 858 + 842 859 static const struct platform_features srf_features = { 843 860 .has_msr_misc_feature_control = 1, 844 861 .has_msr_misc_pwr_mgmt = 1, ··· 1045 1028 { INTEL_EMERALDRAPIDS_X, &spr_features }, 1046 1029 { INTEL_GRANITERAPIDS_X, &spr_features }, 1047 1030 { INTEL_GRANITERAPIDS_D, &spr_features }, 1031 + { INTEL_PANTHERCOVE_X, &dmr_features }, 1048 1032 { INTEL_LAKEFIELD, &cnl_features }, 1049 1033 { INTEL_ALDERLAKE, &adl_features }, 1050 1034 { INTEL_ALDERLAKE_L, &adl_features }, 1051 1035 { INTEL_RAPTORLAKE, &adl_features }, 1052 1036 { INTEL_RAPTORLAKE_P, &adl_features }, 1053 1037 { INTEL_RAPTORLAKE_S, &adl_features }, 1038 + { INTEL_BARTLETTLAKE, &adl_features }, 1054 1039 { INTEL_METEORLAKE, &adl_features }, 1055 1040 { INTEL_METEORLAKE_L, &adl_features }, 1056 1041 { INTEL_ARROWLAKE_H, &adl_features }, ··· 1091 1072 { 1092 1073 int i; 1093 1074 1094 - 1095 1075 if (authentic_amd || hygon_genuine) { 1096 1076 /* fallback to default features on unsupported models */ 1097 1077 force_load++; ··· 1124 1106 if (platform) 1125 1107 return; 1126 1108 1127 - fprintf(stderr, "Unsupported platform detected.\n" 1128 - "\tSee RUN THE LATEST VERSION on turbostat(8)\n"); 1109 + fprintf(stderr, "Unsupported platform detected.\n\tSee RUN THE LATEST VERSION on turbostat(8)\n"); 1129 1110 exit(1); 1130 1111 } 1131 1112 ··· 1144 1127 1145 1128 #define CPU_SUBSET_MAXCPUS 8192 /* need to use before probe... */ 1146 1129 cpu_set_t *cpu_present_set, *cpu_possible_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset; 1147 - size_t cpu_present_setsize, cpu_possible_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size; 1130 + size_t cpu_present_setsize, cpu_possible_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, 1131 + cpu_subset_size; 1148 1132 #define MAX_ADDED_THREAD_COUNTERS 24 1149 1133 #define MAX_ADDED_CORE_COUNTERS 8 1150 1134 #define MAX_ADDED_PACKAGE_COUNTERS 16 ··· 2158 2140 2159 2141 if (fd) 2160 2142 return fd; 2161 - 2143 + #if defined(ANDROID) 2144 + sprintf(pathname, "/dev/msr%d", cpu); 2145 + #else 2162 2146 sprintf(pathname, "/dev/cpu/%d/msr", cpu); 2147 + #endif 2163 2148 fd = open(pathname, O_RDONLY); 2164 2149 if (fd < 0) 2150 + #if defined(ANDROID) 2151 + err(-1, "%s open failed, try chown or chmod +r /dev/msr*, " 2152 + "or run with --no-msr, or run as root", pathname); 2153 + #else 2165 2154 err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, " 2166 2155 "or run with --no-msr, or run as root", pathname); 2167 - 2156 + #endif 2168 2157 fd_percpu[cpu] = fd; 2169 2158 2170 2159 return fd; ··· 2240 2215 return 0; 2241 2216 } 2242 2217 2243 - int probe_rapl_msr(int cpu, off_t offset, int index) 2218 + int add_msr_counter(int cpu, off_t offset) 2244 2219 { 2245 2220 ssize_t retval; 2246 2221 unsigned long long value; 2247 2222 2248 - assert(!no_msr); 2223 + if (no_msr) 2224 + return -1; 2225 + 2226 + if (!offset) 2227 + return -1; 2249 2228 2250 2229 retval = pread(get_msr_fd(cpu), &value, sizeof(value), offset); 2251 2230 2252 2231 /* if the read failed, the probe fails */ 2253 2232 if (retval != sizeof(value)) 2254 - return 1; 2233 + return -1; 2255 2234 2256 - /* If an Energy Status Counter MSR returns 0, the probe fails */ 2257 - switch (index) { 2235 + if (value == 0) 2236 + return 0; 2237 + 2238 + return 1; 2239 + } 2240 + 2241 + int add_rapl_msr_counter(int cpu, const struct rapl_counter_arch_info *cai) 2242 + { 2243 + int ret; 2244 + 2245 + if (!(platform->rapl_msrs & cai->feature_mask)) 2246 + return -1; 2247 + 2248 + ret = add_msr_counter(cpu, cai->msr); 2249 + if (ret < 0) 2250 + return -1; 2251 + 2252 + switch (cai->rci_index) { 2258 2253 case RAPL_RCI_INDEX_ENERGY_PKG: 2259 2254 case RAPL_RCI_INDEX_ENERGY_CORES: 2260 2255 case RAPL_RCI_INDEX_DRAM: 2261 2256 case RAPL_RCI_INDEX_GFX: 2262 2257 case RAPL_RCI_INDEX_ENERGY_PLATFORM: 2263 - if (value == 0) 2258 + if (ret == 0) 2264 2259 return 1; 2265 2260 } 2266 2261 2267 2262 /* PKG,DRAM_PERF_STATUS MSRs, can return any value */ 2268 - return 0; 2263 + return 1; 2269 2264 } 2270 2265 2271 2266 /* Convert CPU ID to domain ID for given added perf counter. */ ··· 2372 2327 " degrees Celsius\n" 2373 2328 " -h, --help\n" 2374 2329 " print this help message\n" 2375 - " -v, --version\n" 2376 - " print version information\n\nFor more help, run \"man turbostat\"\n"); 2330 + " -v, --version\n\t\tprint version information\n\nFor more help, run \"man turbostat\"\n"); 2377 2331 } 2378 2332 2379 2333 /* ··· 2688 2644 if (DO_BIC(BIC_SYS_LPI)) 2689 2645 outp += sprintf(outp, "%sSYS%%LPI", (printed++ ? delim : "")); 2690 2646 2691 - if (platform->rapl_msrs && !rapl_joules) { 2647 + if (!rapl_joules) { 2692 2648 if (DO_BIC(BIC_PkgWatt)) 2693 2649 outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : "")); 2694 2650 if (DO_BIC(BIC_CorWatt) && !platform->has_per_core_rapl) ··· 2701 2657 outp += sprintf(outp, "%sPKG_%%", (printed++ ? delim : "")); 2702 2658 if (DO_BIC(BIC_RAM__)) 2703 2659 outp += sprintf(outp, "%sRAM_%%", (printed++ ? delim : "")); 2704 - } else if (platform->rapl_msrs && rapl_joules) { 2660 + } else { 2705 2661 if (DO_BIC(BIC_Pkg_J)) 2706 2662 outp += sprintf(outp, "%sPkg_J", (printed++ ? delim : "")); 2707 2663 if (DO_BIC(BIC_Cor_J) && !platform->has_per_core_rapl) ··· 3987 3943 if (average.threads.nmi_count > 9999999) 3988 3944 sums_need_wide_columns = 1; 3989 3945 3990 - 3991 3946 average.cores.c3 /= topo.allowed_cores; 3992 3947 average.cores.c6 /= topo.allowed_cores; 3993 3948 average.cores.c7 /= topo.allowed_cores; ··· 4809 4766 return (value & value_mask) >> value_shift; 4810 4767 } 4811 4768 4769 + /* Rapl domain enumeration helpers */ 4770 + static inline int get_rapl_num_domains(void) 4771 + { 4772 + int num_packages = topo.max_package_id + 1; 4773 + int num_cores_per_package; 4774 + int num_cores; 4775 + 4776 + if (!platform->has_per_core_rapl) 4777 + return num_packages; 4778 + 4779 + num_cores_per_package = topo.max_core_id + 1; 4780 + num_cores = num_cores_per_package * num_packages; 4781 + 4782 + return num_cores; 4783 + } 4784 + 4785 + static inline int get_rapl_domain_id(int cpu) 4786 + { 4787 + int nr_cores_per_package = topo.max_core_id + 1; 4788 + int rapl_core_id; 4789 + 4790 + if (!platform->has_per_core_rapl) 4791 + return cpus[cpu].physical_package_id; 4792 + 4793 + /* Compute the system-wide unique core-id for @cpu */ 4794 + rapl_core_id = cpus[cpu].physical_core_id; 4795 + rapl_core_id += cpus[cpu].physical_package_id * nr_cores_per_package; 4796 + 4797 + return rapl_core_id; 4798 + } 4799 + 4812 4800 /* 4813 4801 * get_counters(...) 4814 4802 * migrate to cpu ··· 4895 4821 goto done; 4896 4822 4897 4823 if (platform->has_per_core_rapl) { 4898 - status = get_rapl_counters(cpu, c->core_id, c, p); 4824 + status = get_rapl_counters(cpu, get_rapl_domain_id(cpu), c, p); 4899 4825 if (status != 0) 4900 4826 return status; 4901 4827 } ··· 4961 4887 p->sys_lpi = cpuidle_cur_sys_lpi_us; 4962 4888 4963 4889 if (!platform->has_per_core_rapl) { 4964 - status = get_rapl_counters(cpu, p->package_id, c, p); 4890 + status = get_rapl_counters(cpu, get_rapl_domain_id(cpu), c, p); 4965 4891 if (status != 0) 4966 4892 return status; 4967 4893 } ··· 6550 6476 6551 6477 if (no_msr) 6552 6478 return; 6553 - 6479 + #if defined(ANDROID) 6480 + sprintf(pathname, "/dev/msr%d", base_cpu); 6481 + #else 6554 6482 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); 6483 + #endif 6555 6484 if (stat(pathname, &sb)) 6556 6485 if (system("/sbin/modprobe msr > /dev/null 2>&1")) 6557 6486 no_msr = 1; ··· 6604 6527 failed += check_for_cap_sys_rawio(); 6605 6528 6606 6529 /* test file permissions */ 6530 + #if defined(ANDROID) 6531 + sprintf(pathname, "/dev/msr%d", base_cpu); 6532 + #else 6607 6533 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); 6534 + #endif 6608 6535 if (euidaccess(pathname, R_OK)) { 6609 6536 failed++; 6610 6537 } ··· 6818 6737 * This allows "--show/--hide UncMHz" to be effective for 6819 6738 * the clustered MHz counters, as a group. 6820 6739 */ 6821 - if BIC_IS_ENABLED(BIC_UNCORE_MHZ) 6822 - add_counter(0, path, name_buf, 0, SCOPE_PACKAGE, COUNTER_K2M, FORMAT_AVERAGE, 0, package_id); 6740 + if BIC_IS_ENABLED 6741 + (BIC_UNCORE_MHZ) 6742 + add_counter(0, path, name_buf, 0, SCOPE_PACKAGE, COUNTER_K2M, FORMAT_AVERAGE, 0, 6743 + package_id); 6823 6744 6824 6745 if (quiet) 6825 6746 continue; ··· 6893 6810 else 6894 6811 goto next; 6895 6812 6896 - set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms", gt0_is_gt ? GFX_rc6 : SAM_mc6); 6813 + set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms", 6814 + gt0_is_gt ? GFX_rc6 : SAM_mc6); 6897 6815 6898 6816 set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/freq0/cur_freq", gt0_is_gt ? GFX_MHz : SAM_MHz); 6899 6817 6900 - set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/freq0/act_freq", gt0_is_gt ? GFX_ACTMHz : SAM_ACTMHz); 6818 + set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/freq0/act_freq", 6819 + gt0_is_gt ? GFX_ACTMHz : SAM_ACTMHz); 6901 6820 6902 - set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/gtidle/idle_residency_ms", gt0_is_gt ? SAM_mc6 : GFX_rc6); 6821 + set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/gtidle/idle_residency_ms", 6822 + gt0_is_gt ? SAM_mc6 : GFX_rc6); 6903 6823 6904 6824 set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/freq0/cur_freq", gt0_is_gt ? SAM_MHz : GFX_MHz); 6905 6825 6906 - set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/freq0/act_freq", gt0_is_gt ? SAM_ACTMHz : GFX_ACTMHz); 6826 + set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/freq0/act_freq", 6827 + gt0_is_gt ? SAM_ACTMHz : GFX_ACTMHz); 6907 6828 6908 6829 goto end; 6909 6830 } ··· 7343 7256 else 7344 7257 bic_enabled &= ~bic_joules_bits; 7345 7258 7259 + if (!platform->rapl_msrs || no_msr) 7260 + return; 7261 + 7346 7262 if (!(platform->rapl_msrs & RAPL_PKG_PERF_STATUS)) 7347 7263 bic_enabled &= ~BIC_PKG__; 7348 7264 if (!(platform->rapl_msrs & RAPL_DRAM_PERF_STATUS)) ··· 7396 7306 else 7397 7307 bic_enabled &= ~bic_joules_bits; 7398 7308 7309 + if (!platform->rapl_msrs || no_msr) 7310 + return; 7311 + 7399 7312 if (get_msr(base_cpu, MSR_RAPL_PWR_UNIT, &msr)) 7400 7313 return; 7401 7314 ··· 7423 7330 (((msr >> 16) & 1) ? "EN" : "DIS")); 7424 7331 7425 7332 return; 7333 + } 7334 + 7335 + static int fread_int(char *path, int *val) 7336 + { 7337 + FILE *filep; 7338 + int ret; 7339 + 7340 + filep = fopen(path, "r"); 7341 + if (!filep) 7342 + return -1; 7343 + 7344 + ret = fscanf(filep, "%d", val); 7345 + fclose(filep); 7346 + return ret; 7347 + } 7348 + 7349 + static int fread_ull(char *path, unsigned long long *val) 7350 + { 7351 + FILE *filep; 7352 + int ret; 7353 + 7354 + filep = fopen(path, "r"); 7355 + if (!filep) 7356 + return -1; 7357 + 7358 + ret = fscanf(filep, "%llu", val); 7359 + fclose(filep); 7360 + return ret; 7361 + } 7362 + 7363 + static int fread_str(char *path, char *buf, int size) 7364 + { 7365 + FILE *filep; 7366 + int ret; 7367 + char *cp; 7368 + 7369 + filep = fopen(path, "r"); 7370 + if (!filep) 7371 + return -1; 7372 + 7373 + ret = fread(buf, 1, size, filep); 7374 + fclose(filep); 7375 + 7376 + /* replace '\n' with '\0' */ 7377 + cp = strchr(buf, '\n'); 7378 + if (cp != NULL) 7379 + *cp = '\0'; 7380 + 7381 + return ret; 7382 + } 7383 + 7384 + #define PATH_RAPL_SYSFS "/sys/class/powercap" 7385 + 7386 + static int dump_one_domain(char *domain_path) 7387 + { 7388 + char path[PATH_MAX]; 7389 + char str[PATH_MAX]; 7390 + unsigned long long val; 7391 + int constraint; 7392 + int enable; 7393 + int ret; 7394 + 7395 + snprintf(path, PATH_MAX, "%s/name", domain_path); 7396 + ret = fread_str(path, str, PATH_MAX); 7397 + if (ret <= 0) 7398 + return -1; 7399 + 7400 + fprintf(outf, "%s: %s", domain_path + strlen(PATH_RAPL_SYSFS) + 1, str); 7401 + 7402 + snprintf(path, PATH_MAX, "%s/enabled", domain_path); 7403 + ret = fread_int(path, &enable); 7404 + if (ret <= 0) 7405 + return -1; 7406 + 7407 + if (!enable) { 7408 + fputs(" disabled\n", outf); 7409 + return 0; 7410 + } 7411 + 7412 + for (constraint = 0;; constraint++) { 7413 + snprintf(path, PATH_MAX, "%s/constraint_%d_time_window_us", domain_path, constraint); 7414 + ret = fread_ull(path, &val); 7415 + if (ret <= 0) 7416 + break; 7417 + 7418 + if (val > 1000000) 7419 + fprintf(outf, " %0.1fs", (double)val / 1000000); 7420 + else if (val > 1000) 7421 + fprintf(outf, " %0.1fms", (double)val / 1000); 7422 + else 7423 + fprintf(outf, " %0.1fus", (double)val); 7424 + 7425 + snprintf(path, PATH_MAX, "%s/constraint_%d_power_limit_uw", domain_path, constraint); 7426 + ret = fread_ull(path, &val); 7427 + if (ret > 0 && val) 7428 + fprintf(outf, ":%lluW", val / 1000000); 7429 + 7430 + snprintf(path, PATH_MAX, "%s/constraint_%d_max_power_uw", domain_path, constraint); 7431 + ret = fread_ull(path, &val); 7432 + if (ret > 0 && val) 7433 + fprintf(outf, ",max:%lluW", val / 1000000); 7434 + } 7435 + fputc('\n', outf); 7436 + 7437 + return 0; 7438 + } 7439 + 7440 + static int print_rapl_sysfs(void) 7441 + { 7442 + DIR *dir, *cdir; 7443 + struct dirent *entry, *centry; 7444 + char path[PATH_MAX]; 7445 + char str[PATH_MAX]; 7446 + 7447 + if ((dir = opendir(PATH_RAPL_SYSFS)) == NULL) { 7448 + warn("open %s failed", PATH_RAPL_SYSFS); 7449 + return 1; 7450 + } 7451 + 7452 + while ((entry = readdir(dir)) != NULL) { 7453 + if (strlen(entry->d_name) > 100) 7454 + continue; 7455 + 7456 + if (strncmp(entry->d_name, "intel-rapl", strlen("intel-rapl"))) 7457 + continue; 7458 + 7459 + snprintf(path, PATH_MAX, "%s/%s/name", PATH_RAPL_SYSFS, entry->d_name); 7460 + 7461 + /* Parse top level domains first, including package and psys */ 7462 + fread_str(path, str, PATH_MAX); 7463 + if (strncmp(str, "package", strlen("package")) && strncmp(str, "psys", strlen("psys"))) 7464 + continue; 7465 + 7466 + snprintf(path, PATH_MAX, "%s/%s", PATH_RAPL_SYSFS, entry->d_name); 7467 + if ((cdir = opendir(path)) == NULL) { 7468 + perror("opendir() error"); 7469 + return 1; 7470 + } 7471 + 7472 + dump_one_domain(path); 7473 + 7474 + while ((centry = readdir(cdir)) != NULL) { 7475 + if (strncmp(centry->d_name, "intel-rapl", strlen("intel-rapl"))) 7476 + continue; 7477 + snprintf(path, PATH_MAX, "%s/%s/%s", PATH_RAPL_SYSFS, entry->d_name, centry->d_name); 7478 + dump_one_domain(path); 7479 + } 7480 + closedir(cdir); 7481 + } 7482 + 7483 + closedir(dir); 7484 + return 0; 7426 7485 } 7427 7486 7428 7487 int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) ··· 7703 7458 */ 7704 7459 void probe_rapl(void) 7705 7460 { 7706 - if (!platform->rapl_msrs || no_msr) 7707 - return; 7708 - 7709 7461 if (genuine_intel) 7710 7462 rapl_probe_intel(); 7711 7463 if (authentic_amd || hygon_genuine) 7712 7464 rapl_probe_amd(); 7713 7465 7714 7466 if (quiet) 7467 + return; 7468 + 7469 + print_rapl_sysfs(); 7470 + 7471 + if (!platform->rapl_msrs || no_msr) 7715 7472 return; 7716 7473 7717 7474 for_all_cpus(print_rapl, ODD_COUNTERS); ··· 8048 7801 return has_access; 8049 7802 } 8050 7803 8051 - int add_rapl_perf_counter_(int cpu, struct rapl_counter_info_t *rci, const struct rapl_counter_arch_info *cai, 8052 - double *scale_, enum rapl_unit *unit_) 7804 + int add_rapl_perf_counter(int cpu, struct rapl_counter_info_t *rci, const struct rapl_counter_arch_info *cai, 7805 + double *scale_, enum rapl_unit *unit_) 8053 7806 { 7807 + int ret = -1; 7808 + 8054 7809 if (no_perf) 7810 + return -1; 7811 + 7812 + if (!cai->perf_name) 8055 7813 return -1; 8056 7814 8057 7815 const double scale = read_perf_scale(cai->perf_subsys, cai->perf_name); 8058 7816 8059 7817 if (scale == 0.0) 8060 - return -1; 7818 + goto end; 8061 7819 8062 7820 const enum rapl_unit unit = read_perf_rapl_unit(cai->perf_subsys, cai->perf_name); 8063 7821 8064 7822 if (unit == RAPL_UNIT_INVALID) 8065 - return -1; 7823 + goto end; 8066 7824 8067 7825 const unsigned int rapl_type = read_perf_type(cai->perf_subsys); 8068 7826 const unsigned int rapl_energy_pkg_config = read_perf_config(cai->perf_subsys, cai->perf_name); 8069 7827 8070 - const int fd_counter = 8071 - open_perf_counter(cpu, rapl_type, rapl_energy_pkg_config, rci->fd_perf, PERF_FORMAT_GROUP); 8072 - if (fd_counter == -1) 8073 - return -1; 7828 + ret = open_perf_counter(cpu, rapl_type, rapl_energy_pkg_config, rci->fd_perf, PERF_FORMAT_GROUP); 7829 + if (ret == -1) 7830 + goto end; 8074 7831 8075 7832 /* If it's the first counter opened, make it a group descriptor */ 8076 7833 if (rci->fd_perf == -1) 8077 - rci->fd_perf = fd_counter; 7834 + rci->fd_perf = ret; 8078 7835 8079 7836 *scale_ = scale; 8080 7837 *unit_ = unit; 8081 - return fd_counter; 8082 - } 8083 7838 8084 - int add_rapl_perf_counter(int cpu, struct rapl_counter_info_t *rci, const struct rapl_counter_arch_info *cai, 8085 - double *scale, enum rapl_unit *unit) 8086 - { 8087 - int ret = add_rapl_perf_counter_(cpu, rci, cai, scale, unit); 8088 - 7839 + end: 8089 7840 if (debug >= 2) 8090 7841 fprintf(stderr, "%s: %d (cpu: %d)\n", __func__, ret, cpu); 8091 7842 ··· 8108 7863 8109 7864 void rapl_perf_init(void) 8110 7865 { 8111 - const unsigned int num_domains = (platform->has_per_core_rapl ? topo.max_core_id : topo.max_package_id) + 1; 7866 + const unsigned int num_domains = get_rapl_num_domains(); 8112 7867 bool *domain_visited = calloc(num_domains, sizeof(bool)); 8113 7868 8114 7869 rapl_counter_info_perdomain = calloc(num_domains, sizeof(*rapl_counter_info_perdomain)); ··· 8141 7896 enum rapl_unit unit; 8142 7897 unsigned int next_domain; 8143 7898 7899 + if (!BIC_IS_ENABLED(cai->bic)) 7900 + continue; 7901 + 8144 7902 memset(domain_visited, 0, num_domains * sizeof(*domain_visited)); 8145 7903 8146 7904 for (int cpu = 0; cpu < topo.max_cpu_num + 1; ++cpu) { ··· 8152 7904 continue; 8153 7905 8154 7906 /* Skip already seen and handled RAPL domains */ 8155 - next_domain = 8156 - platform->has_per_core_rapl ? cpus[cpu].physical_core_id : cpus[cpu].physical_package_id; 7907 + next_domain = get_rapl_domain_id(cpu); 8157 7908 8158 7909 assert(next_domain < num_domains); 8159 7910 ··· 8166 7919 8167 7920 struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[next_domain]; 8168 7921 8169 - /* Check if the counter is enabled and accessible */ 8170 - if (BIC_IS_ENABLED(cai->bic) && (platform->rapl_msrs & cai->feature_mask)) { 7922 + /* 7923 + * rapl_counter_arch_infos[] can have multiple entries describing the same 7924 + * counter, due to the difference from different platforms/Vendors. 7925 + * E.g. rapl_counter_arch_infos[0] and rapl_counter_arch_infos[1] share the 7926 + * same perf_subsys and perf_name, but with different MSR address. 7927 + * rapl_counter_arch_infos[0] is for Intel and rapl_counter_arch_infos[1] 7928 + * is for AMD. 7929 + * In this case, it is possible that multiple rapl_counter_arch_infos[] 7930 + * entries are probed just because their perf/msr is duplicate and valid. 7931 + * 7932 + * Thus need a check to avoid re-probe the same counters. 7933 + */ 7934 + if (rci->source[cai->rci_index] != COUNTER_SOURCE_NONE) 7935 + break; 8171 7936 8172 - /* Use perf API for this counter */ 8173 - if (!no_perf && cai->perf_name 8174 - && add_rapl_perf_counter(cpu, rci, cai, &scale, &unit) != -1) { 8175 - rci->source[cai->rci_index] = COUNTER_SOURCE_PERF; 8176 - rci->scale[cai->rci_index] = scale * cai->compat_scale; 8177 - rci->unit[cai->rci_index] = unit; 8178 - rci->flags[cai->rci_index] = cai->flags; 7937 + /* Use perf API for this counter */ 7938 + if (add_rapl_perf_counter(cpu, rci, cai, &scale, &unit) != -1) { 7939 + rci->source[cai->rci_index] = COUNTER_SOURCE_PERF; 7940 + rci->scale[cai->rci_index] = scale * cai->compat_scale; 7941 + rci->unit[cai->rci_index] = unit; 7942 + rci->flags[cai->rci_index] = cai->flags; 8179 7943 8180 - /* Use MSR for this counter */ 8181 - } else if (!no_msr && cai->msr && probe_rapl_msr(cpu, cai->msr, cai->rci_index) == 0) { 8182 - rci->source[cai->rci_index] = COUNTER_SOURCE_MSR; 8183 - rci->msr[cai->rci_index] = cai->msr; 8184 - rci->msr_mask[cai->rci_index] = cai->msr_mask; 8185 - rci->msr_shift[cai->rci_index] = cai->msr_shift; 8186 - rci->unit[cai->rci_index] = RAPL_UNIT_JOULES; 8187 - rci->scale[cai->rci_index] = *cai->platform_rapl_msr_scale * cai->compat_scale; 8188 - rci->flags[cai->rci_index] = cai->flags; 8189 - } 7944 + /* Use MSR for this counter */ 7945 + } else if (add_rapl_msr_counter(cpu, cai) >= 0) { 7946 + rci->source[cai->rci_index] = COUNTER_SOURCE_MSR; 7947 + rci->msr[cai->rci_index] = cai->msr; 7948 + rci->msr_mask[cai->rci_index] = cai->msr_mask; 7949 + rci->msr_shift[cai->rci_index] = cai->msr_shift; 7950 + rci->unit[cai->rci_index] = RAPL_UNIT_JOULES; 7951 + rci->scale[cai->rci_index] = *cai->platform_rapl_msr_scale * cai->compat_scale; 7952 + rci->flags[cai->rci_index] = cai->flags; 8190 7953 } 8191 7954 8192 7955 if (rci->source[cai->rci_index] != COUNTER_SOURCE_NONE) ··· 8229 7972 return NULL; 8230 7973 } 8231 7974 8232 - int add_cstate_perf_counter_(int cpu, struct cstate_counter_info_t *cci, const struct cstate_counter_arch_info *cai) 7975 + int add_cstate_perf_counter(int cpu, struct cstate_counter_info_t *cci, const struct cstate_counter_arch_info *cai) 8233 7976 { 7977 + int ret = -1; 7978 + 8234 7979 if (no_perf) 7980 + return -1; 7981 + 7982 + if (!cai->perf_name) 8235 7983 return -1; 8236 7984 8237 7985 int *pfd_group = get_cstate_perf_group_fd(cci, cai->perf_subsys); 8238 7986 8239 7987 if (pfd_group == NULL) 8240 - return -1; 7988 + goto end; 8241 7989 8242 7990 const unsigned int type = read_perf_type(cai->perf_subsys); 8243 7991 const unsigned int config = read_perf_config(cai->perf_subsys, cai->perf_name); 8244 7992 8245 - const int fd_counter = open_perf_counter(cpu, type, config, *pfd_group, PERF_FORMAT_GROUP); 7993 + ret = open_perf_counter(cpu, type, config, *pfd_group, PERF_FORMAT_GROUP); 8246 7994 8247 - if (fd_counter == -1) 8248 - return -1; 7995 + if (ret == -1) 7996 + goto end; 8249 7997 8250 7998 /* If it's the first counter opened, make it a group descriptor */ 8251 7999 if (*pfd_group == -1) 8252 - *pfd_group = fd_counter; 8000 + *pfd_group = ret; 8253 8001 8254 - return fd_counter; 8255 - } 8256 - 8257 - int add_cstate_perf_counter(int cpu, struct cstate_counter_info_t *cci, const struct cstate_counter_arch_info *cai) 8258 - { 8259 - int ret = add_cstate_perf_counter_(cpu, cci, cai); 8260 - 8002 + end: 8261 8003 if (debug >= 2) 8262 8004 fprintf(stderr, "%s: %d (cpu: %d)\n", __func__, ret, cpu); 8263 8005 8264 8006 return ret; 8265 8007 } 8266 8008 8267 - int add_msr_perf_counter_(int cpu, struct msr_counter_info_t *cci, const struct msr_counter_arch_info *cai) 8009 + int add_msr_perf_counter(int cpu, struct msr_counter_info_t *cci, const struct msr_counter_arch_info *cai) 8268 8010 { 8011 + int ret = -1; 8012 + 8269 8013 if (no_perf) 8014 + return -1; 8015 + 8016 + if (!cai->perf_name) 8270 8017 return -1; 8271 8018 8272 8019 const unsigned int type = read_perf_type(cai->perf_subsys); 8273 8020 const unsigned int config = read_perf_config(cai->perf_subsys, cai->perf_name); 8274 8021 8275 - const int fd_counter = open_perf_counter(cpu, type, config, cci->fd_perf, PERF_FORMAT_GROUP); 8022 + ret = open_perf_counter(cpu, type, config, cci->fd_perf, PERF_FORMAT_GROUP); 8276 8023 8277 - if (fd_counter == -1) 8278 - return -1; 8024 + if (ret == -1) 8025 + goto end; 8279 8026 8280 8027 /* If it's the first counter opened, make it a group descriptor */ 8281 8028 if (cci->fd_perf == -1) 8282 - cci->fd_perf = fd_counter; 8029 + cci->fd_perf = ret; 8283 8030 8284 - return fd_counter; 8285 - } 8286 - 8287 - int add_msr_perf_counter(int cpu, struct msr_counter_info_t *cci, const struct msr_counter_arch_info *cai) 8288 - { 8289 - int ret = add_msr_perf_counter_(cpu, cci, cai); 8290 - 8031 + end: 8291 8032 if (debug) 8292 8033 fprintf(stderr, "%s: %s/%s: %d (cpu: %d)\n", __func__, cai->perf_subsys, cai->perf_name, ret, cpu); 8293 8034 ··· 8319 8064 8320 8065 if (cai->needed) { 8321 8066 /* Use perf API for this counter */ 8322 - if (!no_perf && cai->perf_name && add_msr_perf_counter(cpu, cci, cai) != -1) { 8067 + if (add_msr_perf_counter(cpu, cci, cai) != -1) { 8323 8068 cci->source[cai->rci_index] = COUNTER_SOURCE_PERF; 8324 8069 cai->present = true; 8325 8070 8326 8071 /* User MSR for this counter */ 8327 - } else if (!no_msr && cai->msr && probe_rapl_msr(cpu, cai->msr, cai->rci_index) == 0) { 8072 + } else if (add_msr_counter(cpu, cai->msr) >= 0) { 8328 8073 cci->source[cai->rci_index] = COUNTER_SOURCE_MSR; 8329 8074 cci->msr[cai->rci_index] = cai->msr; 8330 8075 cci->msr_mask[cai->rci_index] = cai->msr_mask; ··· 8432 8177 8433 8178 if (counter_needed && counter_supported) { 8434 8179 /* Use perf API for this counter */ 8435 - if (!no_perf && cai->perf_name && add_cstate_perf_counter(cpu, cci, cai) != -1) { 8180 + if (add_cstate_perf_counter(cpu, cci, cai) != -1) { 8436 8181 8437 8182 cci->source[cai->rci_index] = COUNTER_SOURCE_PERF; 8438 8183 8439 8184 /* User MSR for this counter */ 8440 - } else if (!no_msr && cai->msr && pkg_cstate_limit >= cai->pkg_cstate_limit 8441 - && probe_rapl_msr(cpu, cai->msr, cai->rci_index) == 0) { 8185 + } else if (pkg_cstate_limit >= cai->pkg_cstate_limit 8186 + && add_msr_counter(cpu, cai->msr) >= 0) { 8442 8187 cci->source[cai->rci_index] = COUNTER_SOURCE_MSR; 8443 8188 cci->msr[cai->rci_index] = cai->msr; 8444 8189 } ··· 9299 9044 perf_device = "cpu_atom"; 9300 9045 break; 9301 9046 9302 - default: /* Don't change, we will probably fail and report a problem soon. */ 9047 + default: /* Don't change, we will probably fail and report a problem soon. */ 9303 9048 break; 9304 9049 } 9305 9050 } 9306 9051 9307 9052 perf_type = read_perf_type(perf_device); 9308 9053 if (perf_type == (unsigned int)-1) { 9309 - warnx("%s: perf/%s/%s: failed to read %s", 9310 - __func__, perf_device, pinfo->event, "type"); 9054 + warnx("%s: perf/%s/%s: failed to read %s", __func__, perf_device, pinfo->event, "type"); 9311 9055 continue; 9312 9056 } 9313 9057 ··· 9408 9154 return NULL; 9409 9155 } 9410 9156 9411 - for ( ; entry != NULL; entry = pmt_diriter_next(&pmt_iter)) { 9157 + for (; entry != NULL; entry = pmt_diriter_next(&pmt_iter)) { 9412 9158 if (fstatat(dirfd(pmt_iter.dir), entry->d_name, &st, 0) == -1) 9413 9159 break; 9414 9160 ··· 9848 9594 9849 9595 void print_version() 9850 9596 { 9851 - fprintf(outf, "turbostat version 2025.04.06 - Len Brown <lenb@kernel.org>\n"); 9597 + fprintf(outf, "turbostat version 2025.06.08 - Len Brown <lenb@kernel.org>\n"); 9852 9598 } 9853 9599 9854 9600 #define COMMAND_LINE_SIZE 2048 ··· 10304 10050 unsigned int lsb; 10305 10051 unsigned int msb; 10306 10052 unsigned int guid; 10307 - unsigned int seq = 0; /* By default, pick first file in a sequence with a given GUID. */ 10053 + unsigned int seq = 0; /* By default, pick first file in a sequence with a given GUID. */ 10308 10054 unsigned int domain_id; 10309 10055 enum counter_scope scope = 0; 10310 10056 enum pmt_datatype type = PMT_TYPE_RAW;