diff options
| -rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 159 |
1 files changed, 130 insertions, 29 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 0716abdb1bd9..538878b9deb8 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <cpuid.h> | 44 | #include <cpuid.h> |
| 45 | #include <linux/capability.h> | 45 | #include <linux/capability.h> |
| 46 | #include <errno.h> | 46 | #include <errno.h> |
| 47 | #include <math.h> | ||
| 47 | 48 | ||
| 48 | char *proc_stat = "/proc/stat"; | 49 | char *proc_stat = "/proc/stat"; |
| 49 | FILE *outf; | 50 | FILE *outf; |
| @@ -140,9 +141,21 @@ unsigned int first_counter_read = 1; | |||
| 140 | 141 | ||
| 141 | #define RAPL_CORES_ENERGY_STATUS (1 << 9) | 142 | #define RAPL_CORES_ENERGY_STATUS (1 << 9) |
| 142 | /* 0x639 MSR_PP0_ENERGY_STATUS */ | 143 | /* 0x639 MSR_PP0_ENERGY_STATUS */ |
| 144 | #define RAPL_PER_CORE_ENERGY (1 << 10) | ||
| 145 | /* Indicates cores energy collection is per-core, | ||
| 146 | * not per-package. */ | ||
| 147 | #define RAPL_AMD_F17H (1 << 11) | ||
| 148 | /* 0xc0010299 MSR_RAPL_PWR_UNIT */ | ||
| 149 | /* 0xc001029a MSR_CORE_ENERGY_STAT */ | ||
| 150 | /* 0xc001029b MSR_PKG_ENERGY_STAT */ | ||
| 143 | #define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT) | 151 | #define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT) |
| 144 | #define TJMAX_DEFAULT 100 | 152 | #define TJMAX_DEFAULT 100 |
| 145 | 153 | ||
| 154 | /* MSRs that are not yet in the kernel-provided header. */ | ||
| 155 | #define MSR_RAPL_PWR_UNIT 0xc0010299 | ||
| 156 | #define MSR_CORE_ENERGY_STAT 0xc001029a | ||
| 157 | #define MSR_PKG_ENERGY_STAT 0xc001029b | ||
| 158 | |||
| 146 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) | 159 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) |
| 147 | 160 | ||
| 148 | /* | 161 | /* |
| @@ -186,6 +199,7 @@ struct core_data { | |||
| 186 | unsigned long long c7; | 199 | unsigned long long c7; |
| 187 | unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */ | 200 | unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */ |
| 188 | unsigned int core_temp_c; | 201 | unsigned int core_temp_c; |
| 202 | unsigned int core_energy; /* MSR_CORE_ENERGY_STAT */ | ||
| 189 | unsigned int core_id; | 203 | unsigned int core_id; |
| 190 | unsigned long long counter[MAX_ADDED_COUNTERS]; | 204 | unsigned long long counter[MAX_ADDED_COUNTERS]; |
| 191 | } *core_even, *core_odd; | 205 | } *core_even, *core_odd; |
| @@ -684,6 +698,14 @@ void print_header(char *delim) | |||
| 684 | if (DO_BIC(BIC_CoreTmp)) | 698 | if (DO_BIC(BIC_CoreTmp)) |
| 685 | outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : "")); | 699 | outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : "")); |
| 686 | 700 | ||
| 701 | if (do_rapl && !rapl_joules) { | ||
| 702 | if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY)) | ||
| 703 | outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : "")); | ||
| 704 | } else if (do_rapl && rapl_joules) { | ||
| 705 | if (DO_BIC(BIC_Cor_J) && (do_rapl & RAPL_PER_CORE_ENERGY)) | ||
| 706 | outp += sprintf(outp, "%sCor_J", (printed++ ? delim : "")); | ||
| 707 | } | ||
| 708 | |||
| 687 | for (mp = sys.cp; mp; mp = mp->next) { | 709 | for (mp = sys.cp; mp; mp = mp->next) { |
| 688 | if (mp->format == FORMAT_RAW) { | 710 | if (mp->format == FORMAT_RAW) { |
| 689 | if (mp->width == 64) | 711 | if (mp->width == 64) |
| @@ -738,7 +760,7 @@ void print_header(char *delim) | |||
| 738 | if (do_rapl && !rapl_joules) { | 760 | if (do_rapl && !rapl_joules) { |
| 739 | if (DO_BIC(BIC_PkgWatt)) | 761 | if (DO_BIC(BIC_PkgWatt)) |
| 740 | outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : "")); | 762 | outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : "")); |
| 741 | if (DO_BIC(BIC_CorWatt)) | 763 | if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
| 742 | outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : "")); | 764 | outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : "")); |
| 743 | if (DO_BIC(BIC_GFXWatt)) | 765 | if (DO_BIC(BIC_GFXWatt)) |
| 744 | outp += sprintf(outp, "%sGFXWatt", (printed++ ? delim : "")); | 766 | outp += sprintf(outp, "%sGFXWatt", (printed++ ? delim : "")); |
| @@ -751,7 +773,7 @@ void print_header(char *delim) | |||
| 751 | } else if (do_rapl && rapl_joules) { | 773 | } else if (do_rapl && rapl_joules) { |
| 752 | if (DO_BIC(BIC_Pkg_J)) | 774 | if (DO_BIC(BIC_Pkg_J)) |
| 753 | outp += sprintf(outp, "%sPkg_J", (printed++ ? delim : "")); | 775 | outp += sprintf(outp, "%sPkg_J", (printed++ ? delim : "")); |
| 754 | if (DO_BIC(BIC_Cor_J)) | 776 | if (DO_BIC(BIC_Cor_J) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
| 755 | outp += sprintf(outp, "%sCor_J", (printed++ ? delim : "")); | 777 | outp += sprintf(outp, "%sCor_J", (printed++ ? delim : "")); |
| 756 | if (DO_BIC(BIC_GFX_J)) | 778 | if (DO_BIC(BIC_GFX_J)) |
| 757 | outp += sprintf(outp, "%sGFX_J", (printed++ ? delim : "")); | 779 | outp += sprintf(outp, "%sGFX_J", (printed++ ? delim : "")); |
| @@ -812,6 +834,7 @@ int dump_counters(struct thread_data *t, struct core_data *c, | |||
| 812 | outp += sprintf(outp, "c6: %016llX\n", c->c6); | 834 | outp += sprintf(outp, "c6: %016llX\n", c->c6); |
| 813 | outp += sprintf(outp, "c7: %016llX\n", c->c7); | 835 | outp += sprintf(outp, "c7: %016llX\n", c->c7); |
| 814 | outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c); | 836 | outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c); |
| 837 | outp += sprintf(outp, "Joules: %0X\n", c->core_energy); | ||
| 815 | 838 | ||
| 816 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { | 839 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
| 817 | outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n", | 840 | outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n", |
| @@ -1045,6 +1068,20 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
| 1045 | } | 1068 | } |
| 1046 | } | 1069 | } |
| 1047 | 1070 | ||
| 1071 | /* | ||
| 1072 | * If measurement interval exceeds minimum RAPL Joule Counter range, | ||
| 1073 | * indicate that results are suspect by printing "**" in fraction place. | ||
| 1074 | */ | ||
| 1075 | if (interval_float < rapl_joule_counter_range) | ||
| 1076 | fmt8 = "%s%.2f"; | ||
| 1077 | else | ||
| 1078 | fmt8 = "%6.0f**"; | ||
| 1079 | |||
| 1080 | if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY)) | ||
| 1081 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units / interval_float); | ||
| 1082 | if (DO_BIC(BIC_Cor_J) && (do_rapl & RAPL_PER_CORE_ENERGY)) | ||
| 1083 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units); | ||
| 1084 | |||
| 1048 | /* print per-package data only for 1st core in package */ | 1085 | /* print per-package data only for 1st core in package */ |
| 1049 | if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) | 1086 | if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) |
| 1050 | goto done; | 1087 | goto done; |
| @@ -1097,18 +1134,9 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
| 1097 | if (DO_BIC(BIC_SYS_LPI)) | 1134 | if (DO_BIC(BIC_SYS_LPI)) |
| 1098 | outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float); | 1135 | outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float); |
| 1099 | 1136 | ||
| 1100 | /* | ||
| 1101 | * If measurement interval exceeds minimum RAPL Joule Counter range, | ||
| 1102 | * indicate that results are suspect by printing "**" in fraction place. | ||
| 1103 | */ | ||
| 1104 | if (interval_float < rapl_joule_counter_range) | ||
| 1105 | fmt8 = "%s%.2f"; | ||
| 1106 | else | ||
| 1107 | fmt8 = "%6.0f**"; | ||
| 1108 | |||
| 1109 | if (DO_BIC(BIC_PkgWatt)) | 1137 | if (DO_BIC(BIC_PkgWatt)) |
| 1110 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float); | 1138 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float); |
| 1111 | if (DO_BIC(BIC_CorWatt)) | 1139 | if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
| 1112 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float); | 1140 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float); |
| 1113 | if (DO_BIC(BIC_GFXWatt)) | 1141 | if (DO_BIC(BIC_GFXWatt)) |
| 1114 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float); | 1142 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float); |
| @@ -1116,7 +1144,7 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
| 1116 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units / interval_float); | 1144 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units / interval_float); |
| 1117 | if (DO_BIC(BIC_Pkg_J)) | 1145 | if (DO_BIC(BIC_Pkg_J)) |
| 1118 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units); | 1146 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units); |
| 1119 | if (DO_BIC(BIC_Cor_J)) | 1147 | if (DO_BIC(BIC_Cor_J) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
| 1120 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units); | 1148 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units); |
| 1121 | if (DO_BIC(BIC_GFX_J)) | 1149 | if (DO_BIC(BIC_GFX_J)) |
| 1122 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units); | 1150 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units); |
| @@ -1261,6 +1289,8 @@ delta_core(struct core_data *new, struct core_data *old) | |||
| 1261 | old->core_temp_c = new->core_temp_c; | 1289 | old->core_temp_c = new->core_temp_c; |
| 1262 | old->mc6_us = new->mc6_us - old->mc6_us; | 1290 | old->mc6_us = new->mc6_us - old->mc6_us; |
| 1263 | 1291 | ||
| 1292 | DELTA_WRAP32(new->core_energy, old->core_energy); | ||
| 1293 | |||
| 1264 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { | 1294 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
| 1265 | if (mp->format == FORMAT_RAW) | 1295 | if (mp->format == FORMAT_RAW) |
| 1266 | old->counter[i] = new->counter[i]; | 1296 | old->counter[i] = new->counter[i]; |
| @@ -1403,6 +1433,7 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data | |||
| 1403 | c->c7 = 0; | 1433 | c->c7 = 0; |
| 1404 | c->mc6_us = 0; | 1434 | c->mc6_us = 0; |
| 1405 | c->core_temp_c = 0; | 1435 | c->core_temp_c = 0; |
| 1436 | c->core_energy = 0; | ||
| 1406 | 1437 | ||
| 1407 | p->pkg_wtd_core_c0 = 0; | 1438 | p->pkg_wtd_core_c0 = 0; |
| 1408 | p->pkg_any_core_c0 = 0; | 1439 | p->pkg_any_core_c0 = 0; |
| @@ -1485,6 +1516,8 @@ int sum_counters(struct thread_data *t, struct core_data *c, | |||
| 1485 | 1516 | ||
| 1486 | average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c); | 1517 | average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c); |
| 1487 | 1518 | ||
| 1519 | average.cores.core_energy += c->core_energy; | ||
| 1520 | |||
| 1488 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { | 1521 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
| 1489 | if (mp->format == FORMAT_RAW) | 1522 | if (mp->format == FORMAT_RAW) |
| 1490 | continue; | 1523 | continue; |
| @@ -1857,6 +1890,12 @@ retry: | |||
| 1857 | c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); | 1890 | c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); |
| 1858 | } | 1891 | } |
| 1859 | 1892 | ||
| 1893 | if (do_rapl & RAPL_AMD_F17H) { | ||
| 1894 | if (get_msr(cpu, MSR_CORE_ENERGY_STAT, &msr)) | ||
| 1895 | return -14; | ||
| 1896 | c->core_energy = msr & 0xFFFFFFFF; | ||
| 1897 | } | ||
| 1898 | |||
| 1860 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { | 1899 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
| 1861 | if (get_mp(cpu, mp, &c->counter[i])) | 1900 | if (get_mp(cpu, mp, &c->counter[i])) |
| 1862 | return -10; | 1901 | return -10; |
| @@ -3739,7 +3778,7 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data | |||
| 3739 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ | 3778 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ |
| 3740 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ | 3779 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ |
| 3741 | 3780 | ||
| 3742 | double get_tdp(unsigned int model) | 3781 | double get_tdp_intel(unsigned int model) |
| 3743 | { | 3782 | { |
| 3744 | unsigned long long msr; | 3783 | unsigned long long msr; |
| 3745 | 3784 | ||
| @@ -3756,6 +3795,16 @@ double get_tdp(unsigned int model) | |||
| 3756 | } | 3795 | } |
| 3757 | } | 3796 | } |
| 3758 | 3797 | ||
| 3798 | double get_tdp_amd(unsigned int family) | ||
| 3799 | { | ||
| 3800 | switch (family) { | ||
| 3801 | case 0x17: | ||
| 3802 | default: | ||
| 3803 | /* This is the max stock TDP of HEDT/Server Fam17h chips */ | ||
| 3804 | return 250.0; | ||
| 3805 | } | ||
| 3806 | } | ||
| 3807 | |||
| 3759 | /* | 3808 | /* |
| 3760 | * rapl_dram_energy_units_probe() | 3809 | * rapl_dram_energy_units_probe() |
| 3761 | * Energy units are either hard-coded, or come from RAPL Energy Unit MSR. | 3810 | * Energy units are either hard-coded, or come from RAPL Energy Unit MSR. |
| @@ -3775,21 +3824,12 @@ rapl_dram_energy_units_probe(int model, double rapl_energy_units) | |||
| 3775 | } | 3824 | } |
| 3776 | } | 3825 | } |
| 3777 | 3826 | ||
| 3778 | 3827 | void rapl_probe_intel(unsigned int family, unsigned int model) | |
| 3779 | /* | ||
| 3780 | * rapl_probe() | ||
| 3781 | * | ||
| 3782 | * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units | ||
| 3783 | */ | ||
| 3784 | void rapl_probe(unsigned int family, unsigned int model) | ||
| 3785 | { | 3828 | { |
| 3786 | unsigned long long msr; | 3829 | unsigned long long msr; |
| 3787 | unsigned int time_unit; | 3830 | unsigned int time_unit; |
| 3788 | double tdp; | 3831 | double tdp; |
| 3789 | 3832 | ||
| 3790 | if (!genuine_intel) | ||
| 3791 | return; | ||
| 3792 | |||
| 3793 | if (family != 6) | 3833 | if (family != 6) |
| 3794 | return; | 3834 | return; |
| 3795 | 3835 | ||
| @@ -3913,13 +3953,66 @@ void rapl_probe(unsigned int family, unsigned int model) | |||
| 3913 | 3953 | ||
| 3914 | rapl_time_units = 1.0 / (1 << (time_unit)); | 3954 | rapl_time_units = 1.0 / (1 << (time_unit)); |
| 3915 | 3955 | ||
| 3916 | tdp = get_tdp(model); | 3956 | tdp = get_tdp_intel(model); |
| 3917 | 3957 | ||
| 3918 | rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; | 3958 | rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; |
| 3919 | if (!quiet) | 3959 | if (!quiet) |
| 3920 | fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); | 3960 | fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); |
| 3961 | } | ||
| 3921 | 3962 | ||
| 3922 | return; | 3963 | void rapl_probe_amd(unsigned int family, unsigned int model) |
| 3964 | { | ||
| 3965 | unsigned long long msr; | ||
| 3966 | unsigned int eax, ebx, ecx, edx; | ||
| 3967 | unsigned int has_rapl = 0; | ||
| 3968 | double tdp; | ||
| 3969 | |||
| 3970 | if (max_extended_level >= 0x80000007) { | ||
| 3971 | __cpuid(0x80000007, eax, ebx, ecx, edx); | ||
| 3972 | /* RAPL (Fam 17h) */ | ||
| 3973 | has_rapl = edx & (1 << 14); | ||
| 3974 | } | ||
| 3975 | |||
| 3976 | if (!has_rapl) | ||
| 3977 | return; | ||
| 3978 | |||
| 3979 | switch (family) { | ||
| 3980 | case 0x17: /* Zen, Zen+ */ | ||
| 3981 | do_rapl = RAPL_AMD_F17H | RAPL_PER_CORE_ENERGY; | ||
| 3982 | if (rapl_joules) | ||
| 3983 | BIC_PRESENT(BIC_Cor_J); | ||
| 3984 | else | ||
| 3985 | BIC_PRESENT(BIC_CorWatt); | ||
| 3986 | break; | ||
| 3987 | default: | ||
| 3988 | return; | ||
| 3989 | } | ||
| 3990 | |||
| 3991 | if (get_msr(base_cpu, MSR_RAPL_PWR_UNIT, &msr)) | ||
| 3992 | return; | ||
| 3993 | |||
| 3994 | rapl_time_units = ldexp(1.0, -(msr >> 16 & 0xf)); | ||
| 3995 | rapl_energy_units = ldexp(1.0, -(msr >> 8 & 0x1f)); | ||
| 3996 | rapl_power_units = ldexp(1.0, -(msr & 0xf)); | ||
| 3997 | |||
| 3998 | tdp = get_tdp_amd(model); | ||
| 3999 | |||
| 4000 | rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; | ||
| 4001 | if (!quiet) | ||
| 4002 | fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); | ||
| 4003 | } | ||
| 4004 | |||
| 4005 | /* | ||
| 4006 | * rapl_probe() | ||
| 4007 | * | ||
| 4008 | * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units | ||
| 4009 | */ | ||
| 4010 | void rapl_probe(unsigned int family, unsigned int model) | ||
| 4011 | { | ||
| 4012 | if (genuine_intel) | ||
| 4013 | rapl_probe_intel(family, model); | ||
| 4014 | if (authentic_amd) | ||
| 4015 | rapl_probe_amd(family, model); | ||
| 3923 | } | 4016 | } |
| 3924 | 4017 | ||
| 3925 | void perf_limit_reasons_probe(unsigned int family, unsigned int model) | 4018 | void perf_limit_reasons_probe(unsigned int family, unsigned int model) |
| @@ -4024,6 +4117,7 @@ void print_power_limit_msr(int cpu, unsigned long long msr, char *label) | |||
| 4024 | int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) | 4117 | int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) |
| 4025 | { | 4118 | { |
| 4026 | unsigned long long msr; | 4119 | unsigned long long msr; |
| 4120 | const char *msr_name; | ||
| 4027 | int cpu; | 4121 | int cpu; |
| 4028 | 4122 | ||
| 4029 | if (!do_rapl) | 4123 | if (!do_rapl) |
| @@ -4039,10 +4133,17 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
| 4039 | return -1; | 4133 | return -1; |
| 4040 | } | 4134 | } |
| 4041 | 4135 | ||
| 4042 | if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) | 4136 | if (do_rapl & RAPL_AMD_F17H) { |
| 4043 | return -1; | 4137 | msr_name = "MSR_RAPL_PWR_UNIT"; |
| 4138 | if (get_msr(cpu, MSR_RAPL_PWR_UNIT, &msr)) | ||
| 4139 | return -1; | ||
| 4140 | } else { | ||
| 4141 | msr_name = "MSR_RAPL_POWER_UNIT"; | ||
| 4142 | if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) | ||
| 4143 | return -1; | ||
| 4144 | } | ||
| 4044 | 4145 | ||
| 4045 | fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr, | 4146 | fprintf(outf, "cpu%d: %s: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr_name, msr, |
| 4046 | rapl_power_units, rapl_energy_units, rapl_time_units); | 4147 | rapl_power_units, rapl_energy_units, rapl_time_units); |
| 4047 | 4148 | ||
| 4048 | if (do_rapl & RAPL_PKG_POWER_INFO) { | 4149 | if (do_rapl & RAPL_PKG_POWER_INFO) { |
