diff options
author | Len Brown <len.brown@intel.com> | 2014-08-15 02:39:52 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2015-02-09 16:44:24 -0500 |
commit | 3a9a941d0b9361eac81fb763a89fb465f70b1c28 (patch) | |
tree | f596891938916502c5ec83c5bfc2b8a228d06f60 /tools | |
parent | 98481e79b60a50d699b79292ff1b7e56e7fa8425 (diff) |
tools/power turbostat: decode MSR_*_PERF_LIMIT_REASONS
The Processor generation code-named Haswell
added MSR_{CORE | GFX | RING}_PERF_LIMIT_REASONS
to explain when and how the processor limits frequency.
turbostat -v
will now decode these bits.
Each MSR has an "Active" set of bits which describe
current conditions, and a "Logged" set of bits,
which describe what has happened since last cleared.
Turbostat currently doesn't clear the log bits.
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 6f29fc11fde6..58913096d7b2 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -83,6 +83,9 @@ unsigned int tcc_activation_temp; | |||
83 | unsigned int tcc_activation_temp_override; | 83 | unsigned int tcc_activation_temp_override; |
84 | double rapl_power_units, rapl_energy_units, rapl_time_units; | 84 | double rapl_power_units, rapl_energy_units, rapl_time_units; |
85 | double rapl_joule_counter_range; | 85 | double rapl_joule_counter_range; |
86 | unsigned int do_core_perf_limit_reasons; | ||
87 | unsigned int do_gfx_perf_limit_reasons; | ||
88 | unsigned int do_ring_perf_limit_reasons; | ||
86 | 89 | ||
87 | #define RAPL_PKG (1 << 0) | 90 | #define RAPL_PKG (1 << 0) |
88 | /* 0x610 MSR_PKG_POWER_LIMIT */ | 91 | /* 0x610 MSR_PKG_POWER_LIMIT */ |
@@ -1178,6 +1181,7 @@ print_nhm_turbo_ratio_limits: | |||
1178 | if (ratio) | 1181 | if (ratio) |
1179 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n", | 1182 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n", |
1180 | ratio, bclk, ratio * bclk); | 1183 | ratio, bclk, ratio * bclk); |
1184 | |||
1181 | } | 1185 | } |
1182 | 1186 | ||
1183 | void free_all_buffers(void) | 1187 | void free_all_buffers(void) |
@@ -1594,6 +1598,103 @@ int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
1594 | return 0; | 1598 | return 0; |
1595 | } | 1599 | } |
1596 | 1600 | ||
1601 | /* | ||
1602 | * print_perf_limit() | ||
1603 | */ | ||
1604 | int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p) | ||
1605 | { | ||
1606 | unsigned long long msr; | ||
1607 | int cpu; | ||
1608 | |||
1609 | cpu = t->cpu_id; | ||
1610 | |||
1611 | /* per-package */ | ||
1612 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) | ||
1613 | return 0; | ||
1614 | |||
1615 | if (cpu_migrate(cpu)) { | ||
1616 | fprintf(stderr, "Could not migrate to CPU %d\n", cpu); | ||
1617 | return -1; | ||
1618 | } | ||
1619 | |||
1620 | if (do_core_perf_limit_reasons) { | ||
1621 | get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr); | ||
1622 | fprintf(stderr, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr); | ||
1623 | fprintf(stderr, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)", | ||
1624 | (msr & 1 << 0) ? "PROCHOT, " : "", | ||
1625 | (msr & 1 << 1) ? "ThermStatus, " : "", | ||
1626 | (msr & 1 << 2) ? "bit2, " : "", | ||
1627 | (msr & 1 << 4) ? "Graphics, " : "", | ||
1628 | (msr & 1 << 5) ? "Auto-HWP, " : "", | ||
1629 | (msr & 1 << 6) ? "VR-Therm, " : "", | ||
1630 | (msr & 1 << 8) ? "Amps, " : "", | ||
1631 | (msr & 1 << 9) ? "CorePwr, " : "", | ||
1632 | (msr & 1 << 10) ? "PkgPwrL1, " : "", | ||
1633 | (msr & 1 << 11) ? "PkgPwrL2, " : "", | ||
1634 | (msr & 1 << 12) ? "MultiCoreTurbo, " : "", | ||
1635 | (msr & 1 << 13) ? "Transitions, " : "", | ||
1636 | (msr & 1 << 14) ? "bit14, " : "", | ||
1637 | (msr & 1 << 15) ? "bit15, " : ""); | ||
1638 | fprintf(stderr, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n", | ||
1639 | (msr & 1 << 16) ? "PROCHOT, " : "", | ||
1640 | (msr & 1 << 17) ? "ThermStatus, " : "", | ||
1641 | (msr & 1 << 18) ? "bit18, " : "", | ||
1642 | (msr & 1 << 20) ? "Graphics, " : "", | ||
1643 | (msr & 1 << 21) ? "Auto-HWP, " : "", | ||
1644 | (msr & 1 << 22) ? "VR-Therm, " : "", | ||
1645 | (msr & 1 << 24) ? "Amps, " : "", | ||
1646 | (msr & 1 << 25) ? "CorePwr, " : "", | ||
1647 | (msr & 1 << 26) ? "PkgPwrL1, " : "", | ||
1648 | (msr & 1 << 27) ? "PkgPwrL2, " : "", | ||
1649 | (msr & 1 << 28) ? "MultiCoreTurbo, " : "", | ||
1650 | (msr & 1 << 29) ? "Transitions, " : "", | ||
1651 | (msr & 1 << 30) ? "bit30, " : "", | ||
1652 | (msr & 1 << 31) ? "bit31, " : ""); | ||
1653 | |||
1654 | } | ||
1655 | if (do_gfx_perf_limit_reasons) { | ||
1656 | get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr); | ||
1657 | fprintf(stderr, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr); | ||
1658 | fprintf(stderr, " (Active: %s%s%s%s%s%s%s%s)", | ||
1659 | (msr & 1 << 0) ? "PROCHOT, " : "", | ||
1660 | (msr & 1 << 1) ? "ThermStatus, " : "", | ||
1661 | (msr & 1 << 4) ? "Graphics, " : "", | ||
1662 | (msr & 1 << 6) ? "VR-Therm, " : "", | ||
1663 | (msr & 1 << 8) ? "Amps, " : "", | ||
1664 | (msr & 1 << 9) ? "GFXPwr, " : "", | ||
1665 | (msr & 1 << 10) ? "PkgPwrL1, " : "", | ||
1666 | (msr & 1 << 11) ? "PkgPwrL2, " : ""); | ||
1667 | fprintf(stderr, " (Logged: %s%s%s%s%s%s%s%s)\n", | ||
1668 | (msr & 1 << 16) ? "PROCHOT, " : "", | ||
1669 | (msr & 1 << 17) ? "ThermStatus, " : "", | ||
1670 | (msr & 1 << 20) ? "Graphics, " : "", | ||
1671 | (msr & 1 << 22) ? "VR-Therm, " : "", | ||
1672 | (msr & 1 << 24) ? "Amps, " : "", | ||
1673 | (msr & 1 << 25) ? "GFXPwr, " : "", | ||
1674 | (msr & 1 << 26) ? "PkgPwrL1, " : "", | ||
1675 | (msr & 1 << 27) ? "PkgPwrL2, " : ""); | ||
1676 | } | ||
1677 | if (do_ring_perf_limit_reasons) { | ||
1678 | get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr); | ||
1679 | fprintf(stderr, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr); | ||
1680 | fprintf(stderr, " (Active: %s%s%s%s%s%s)", | ||
1681 | (msr & 1 << 0) ? "PROCHOT, " : "", | ||
1682 | (msr & 1 << 1) ? "ThermStatus, " : "", | ||
1683 | (msr & 1 << 6) ? "VR-Therm, " : "", | ||
1684 | (msr & 1 << 8) ? "Amps, " : "", | ||
1685 | (msr & 1 << 10) ? "PkgPwrL1, " : "", | ||
1686 | (msr & 1 << 11) ? "PkgPwrL2, " : ""); | ||
1687 | fprintf(stderr, " (Logged: %s%s%s%s%s%s)\n", | ||
1688 | (msr & 1 << 16) ? "PROCHOT, " : "", | ||
1689 | (msr & 1 << 17) ? "ThermStatus, " : "", | ||
1690 | (msr & 1 << 22) ? "VR-Therm, " : "", | ||
1691 | (msr & 1 << 24) ? "Amps, " : "", | ||
1692 | (msr & 1 << 26) ? "PkgPwrL1, " : "", | ||
1693 | (msr & 1 << 27) ? "PkgPwrL2, " : ""); | ||
1694 | } | ||
1695 | return 0; | ||
1696 | } | ||
1697 | |||
1597 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ | 1698 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ |
1598 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ | 1699 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ |
1599 | 1700 | ||
@@ -1683,6 +1784,27 @@ void rapl_probe(unsigned int family, unsigned int model) | |||
1683 | return; | 1784 | return; |
1684 | } | 1785 | } |
1685 | 1786 | ||
1787 | void perf_limit_reasons_probe(family, model) | ||
1788 | { | ||
1789 | if (!genuine_intel) | ||
1790 | return; | ||
1791 | |||
1792 | if (family != 6) | ||
1793 | return; | ||
1794 | |||
1795 | switch (model) { | ||
1796 | case 0x3C: /* HSW */ | ||
1797 | case 0x45: /* HSW */ | ||
1798 | case 0x46: /* HSW */ | ||
1799 | do_gfx_perf_limit_reasons = 1; | ||
1800 | case 0x3F: /* HSX */ | ||
1801 | do_core_perf_limit_reasons = 1; | ||
1802 | do_ring_perf_limit_reasons = 1; | ||
1803 | default: | ||
1804 | return; | ||
1805 | } | ||
1806 | } | ||
1807 | |||
1686 | int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p) | 1808 | int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p) |
1687 | { | 1809 | { |
1688 | unsigned long long msr; | 1810 | unsigned long long msr; |
@@ -2104,6 +2226,7 @@ void check_cpuid() | |||
2104 | do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); | 2226 | do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); |
2105 | do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model); | 2227 | do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model); |
2106 | rapl_probe(family, model); | 2228 | rapl_probe(family, model); |
2229 | perf_limit_reasons_probe(family, model); | ||
2107 | 2230 | ||
2108 | return; | 2231 | return; |
2109 | } | 2232 | } |
@@ -2342,6 +2465,9 @@ void turbostat_init() | |||
2342 | for_all_cpus(print_epb, ODD_COUNTERS); | 2465 | for_all_cpus(print_epb, ODD_COUNTERS); |
2343 | 2466 | ||
2344 | if (verbose) | 2467 | if (verbose) |
2468 | for_all_cpus(print_perf_limit, ODD_COUNTERS); | ||
2469 | |||
2470 | if (verbose) | ||
2345 | for_all_cpus(print_rapl, ODD_COUNTERS); | 2471 | for_all_cpus(print_rapl, ODD_COUNTERS); |
2346 | 2472 | ||
2347 | for_all_cpus(set_temperature_target, ODD_COUNTERS); | 2473 | for_all_cpus(set_temperature_target, ODD_COUNTERS); |