Power management fixes for v4.11-rc7
- Allow CPUs to be put back online even if the cpufreq driver is unable to work with them (eg. due to missing information from platform firmware), which was the previous behavior expected by users, but changed in the 4.9 time frame (Chen Yu). - Fix a few minor issues in the turbostat utility, introduced mostly during the recent update of it (Len Brown, Doug Smythies). - Fix a cpupower utility bug causing it to report incorrect values for turbo frequencies in some cases (Ben Hutchings). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJY8LH9AAoJEILEb/54YlRxUHgQAJUQjhyCfiGzcJ0vpI0pfTgR MPWlWTtzlSHZ7dlh9iWAaOOjMuGCCylDnZCxo39PXF9EhRfY8xOGqYhhmEyoLtjl wAI5ikysLnZjCpCgXETiLRpLCR/wa9fX0s8VXY1qDdvTiu2HkmW1BnyB/fHLIsC7 dLxkyQyj9DolLsoHRfkd7V3ACLHvKdOsP9U3ul1lRB4r1esEWP8xTdMWQawS26uc g4TSUX9ugMTjZwCn3YUa+k+iMs2DNZAo51uNsBR6szaNK5ZHg0UqDsWJZiGPoO3F tyt4yAPQG97wsuuJ3oMs8A4tWQU97c3HDccSz8+QXd2HtUk90IE8zs9LRQul8D2d FOd0huAm9LJ1TkUKpgiF5tmga831IXJUDnHqieCyRQBiVlUKxLRyngHclBW8YOft FmIzfp8HRhaajk67d5qsMhBtWTpnlPhz+2vvp56VzVVdFoed/6TRJNfenUYpojh9 adn9sxpwOW3TJGGBPBw8QX3DAn36aMOmPY+sRM3NXFhaUGsJJJrOU5oJfnMM/RNd oODV4H5ttjRZbEDE66HaNw4jZv7Gm4yqD6qrT3WGztVNUbQBFPTBju3ExJYU+wmz Bj5kGKsDyT+/2dkgVcMLz1Ylkl0OGPTRFQ+4mtx8RfwQECrojZmBq24OVzRUfV0b ZyrH1fAtTAnwUhp6+L7V =kclf -----END PGP SIGNATURE----- Merge tag 'pm-4.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull power management fixes from Rafael Wysocki: "These fix a cpufreq core regression related to CPU online/offline and several issues in the turbostat and cpupower utilities. Specifics: - Allow CPUs to be put back online even if the cpufreq driver is unable to work with them (eg. due to missing information from platform firmware), which was the previous behavior expected by users, but changed in the 4.9 time frame (Chen Yu). - Fix a few minor issues in the turbostat utility, introduced mostly during the recent update of it (Len Brown, Doug Smythies). - Fix a cpupower utility bug causing it to report incorrect values for turbo frequencies in some cases (Ben Hutchings)" * tag 'pm-4.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: cpupower: Fix turbo frequency reporting for pre-Sandy Bridge cores cpufreq: Bring CPUs up even if cpufreq_online() failed tools/power turbostat: update version number tools/power turbostat: fix impossibly large CPU%c1 value tools/power turbostat: turbostat.8 add missing column definitions tools/power turbostat: update HWP dump to decimal from hex tools/power turbostat: enable package THERM_INTERRUPT dump tools/power turbostat: show missing Core and GFX power on SKL and KBL tools/power turbostat: bugfix: GFXMHz column not changing
This commit is contained in:
commit
e16d8b6e1f
|
@ -2398,6 +2398,20 @@ EXPORT_SYMBOL_GPL(cpufreq_boost_enabled);
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
static enum cpuhp_state hp_online;
|
static enum cpuhp_state hp_online;
|
||||||
|
|
||||||
|
static int cpuhp_cpufreq_online(unsigned int cpu)
|
||||||
|
{
|
||||||
|
cpufreq_online(cpu);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cpuhp_cpufreq_offline(unsigned int cpu)
|
||||||
|
{
|
||||||
|
cpufreq_offline(cpu);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpufreq_register_driver - register a CPU Frequency driver
|
* cpufreq_register_driver - register a CPU Frequency driver
|
||||||
* @driver_data: A struct cpufreq_driver containing the values#
|
* @driver_data: A struct cpufreq_driver containing the values#
|
||||||
|
@ -2460,8 +2474,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "cpufreq:online",
|
ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "cpufreq:online",
|
||||||
cpufreq_online,
|
cpuhp_cpufreq_online,
|
||||||
cpufreq_offline);
|
cpuhp_cpufreq_offline);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_if_unreg;
|
goto err_if_unreg;
|
||||||
hp_online = ret;
|
hp_online = ret;
|
||||||
|
|
|
@ -156,6 +156,7 @@ out:
|
||||||
*/
|
*/
|
||||||
case 0x2C: /* Westmere EP - Gulftown */
|
case 0x2C: /* Westmere EP - Gulftown */
|
||||||
cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
|
cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
|
||||||
|
break;
|
||||||
case 0x2A: /* SNB */
|
case 0x2A: /* SNB */
|
||||||
case 0x2D: /* SNB Xeon */
|
case 0x2D: /* SNB Xeon */
|
||||||
case 0x3A: /* IVB */
|
case 0x3A: /* IVB */
|
||||||
|
|
|
@ -100,6 +100,8 @@ The system configuration dump (if --quiet is not used) is followed by statistics
|
||||||
\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states. These numbers are from hardware residency counters.
|
\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states. These numbers are from hardware residency counters.
|
||||||
\fBCoreTmp\fP Degrees Celsius reported by the per-core Digital Thermal Sensor.
|
\fBCoreTmp\fP Degrees Celsius reported by the per-core Digital Thermal Sensor.
|
||||||
\fBPkgTtmp\fP Degrees Celsius reported by the per-package Package Thermal Monitor.
|
\fBPkgTtmp\fP Degrees Celsius reported by the per-package Package Thermal Monitor.
|
||||||
|
\fBGFX%rc6\fP The percentage of time the GPU is in the "render C6" state, rc6, during the measurement interval. From /sys/class/drm/card0/power/rc6_residency_ms.
|
||||||
|
\fBGFXMHz\fP Instantaneous snapshot of what sysfs presents at the end of the measurement interval. From /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz.
|
||||||
\fBPkg%pc2, Pkg%pc3, Pkg%pc6, Pkg%pc7\fP percentage residency in hardware package idle states. These numbers are from hardware residency counters.
|
\fBPkg%pc2, Pkg%pc3, Pkg%pc6, Pkg%pc7\fP percentage residency in hardware package idle states. These numbers are from hardware residency counters.
|
||||||
\fBPkgWatt\fP Watts consumed by the whole package.
|
\fBPkgWatt\fP Watts consumed by the whole package.
|
||||||
\fBCorWatt\fP Watts consumed by the core part of the package.
|
\fBCorWatt\fP Watts consumed by the core part of the package.
|
||||||
|
|
|
@ -1142,7 +1142,7 @@ delta_thread(struct thread_data *new, struct thread_data *old,
|
||||||
* it is possible for mperf's non-halted cycles + idle states
|
* it is possible for mperf's non-halted cycles + idle states
|
||||||
* to exceed TSC's all cycles: show c1 = 0% in that case.
|
* to exceed TSC's all cycles: show c1 = 0% in that case.
|
||||||
*/
|
*/
|
||||||
if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc)
|
if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > (old->tsc * tsc_tweak))
|
||||||
old->c1 = 0;
|
old->c1 = 0;
|
||||||
else {
|
else {
|
||||||
/* normal case, derive c1 */
|
/* normal case, derive c1 */
|
||||||
|
@ -2485,8 +2485,10 @@ int snapshot_gfx_mhz(void)
|
||||||
|
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
|
fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
|
||||||
else
|
else {
|
||||||
rewind(fp);
|
rewind(fp);
|
||||||
|
fflush(fp);
|
||||||
|
}
|
||||||
|
|
||||||
retval = fscanf(fp, "%d", &gfx_cur_mhz);
|
retval = fscanf(fp, "%d", &gfx_cur_mhz);
|
||||||
if (retval != 1)
|
if (retval != 1)
|
||||||
|
@ -3111,7 +3113,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
|
fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
|
||||||
"(high 0x%x guar 0x%x eff 0x%x low 0x%x)\n",
|
"(high %d guar %d eff %d low %d)\n",
|
||||||
cpu, msr,
|
cpu, msr,
|
||||||
(unsigned int)HWP_HIGHEST_PERF(msr),
|
(unsigned int)HWP_HIGHEST_PERF(msr),
|
||||||
(unsigned int)HWP_GUARANTEED_PERF(msr),
|
(unsigned int)HWP_GUARANTEED_PERF(msr),
|
||||||
|
@ -3122,7 +3124,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
|
fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
|
||||||
"(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x pkg 0x%x)\n",
|
"(min %d max %d des %d epp 0x%x window 0x%x pkg 0x%x)\n",
|
||||||
cpu, msr,
|
cpu, msr,
|
||||||
(unsigned int)(((msr) >> 0) & 0xff),
|
(unsigned int)(((msr) >> 0) & 0xff),
|
||||||
(unsigned int)(((msr) >> 8) & 0xff),
|
(unsigned int)(((msr) >> 8) & 0xff),
|
||||||
|
@ -3136,7 +3138,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
|
fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
|
||||||
"(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x)\n",
|
"(min %d max %d des %d epp 0x%x window 0x%x)\n",
|
||||||
cpu, msr,
|
cpu, msr,
|
||||||
(unsigned int)(((msr) >> 0) & 0xff),
|
(unsigned int)(((msr) >> 0) & 0xff),
|
||||||
(unsigned int)(((msr) >> 8) & 0xff),
|
(unsigned int)(((msr) >> 8) & 0xff),
|
||||||
|
@ -3353,17 +3355,19 @@ void rapl_probe(unsigned int family, unsigned int model)
|
||||||
case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
|
case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
|
||||||
case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
|
case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
|
||||||
case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
|
case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
|
||||||
do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
|
do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO;
|
||||||
BIC_PRESENT(BIC_PKG__);
|
BIC_PRESENT(BIC_PKG__);
|
||||||
BIC_PRESENT(BIC_RAM__);
|
BIC_PRESENT(BIC_RAM__);
|
||||||
if (rapl_joules) {
|
if (rapl_joules) {
|
||||||
BIC_PRESENT(BIC_Pkg_J);
|
BIC_PRESENT(BIC_Pkg_J);
|
||||||
BIC_PRESENT(BIC_Cor_J);
|
BIC_PRESENT(BIC_Cor_J);
|
||||||
BIC_PRESENT(BIC_RAM_J);
|
BIC_PRESENT(BIC_RAM_J);
|
||||||
|
BIC_PRESENT(BIC_GFX_J);
|
||||||
} else {
|
} else {
|
||||||
BIC_PRESENT(BIC_PkgWatt);
|
BIC_PRESENT(BIC_PkgWatt);
|
||||||
BIC_PRESENT(BIC_CorWatt);
|
BIC_PRESENT(BIC_CorWatt);
|
||||||
BIC_PRESENT(BIC_RAMWatt);
|
BIC_PRESENT(BIC_RAMWatt);
|
||||||
|
BIC_PRESENT(BIC_GFXWatt);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INTEL_FAM6_HASWELL_X: /* HSX */
|
case INTEL_FAM6_HASWELL_X: /* HSX */
|
||||||
|
@ -3478,7 +3482,7 @@ void perf_limit_reasons_probe(unsigned int family, unsigned int model)
|
||||||
int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
|
int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
|
||||||
{
|
{
|
||||||
unsigned long long msr;
|
unsigned long long msr;
|
||||||
unsigned int dts;
|
unsigned int dts, dts2;
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
if (!(do_dts || do_ptm))
|
if (!(do_dts || do_ptm))
|
||||||
|
@ -3503,7 +3507,6 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p
|
||||||
fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
|
fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
|
||||||
cpu, msr, tcc_activation_temp - dts);
|
cpu, msr, tcc_activation_temp - dts);
|
||||||
|
|
||||||
#ifdef THERM_DEBUG
|
|
||||||
if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
|
if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -3511,11 +3514,10 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p
|
||||||
dts2 = (msr >> 8) & 0x7F;
|
dts2 = (msr >> 8) & 0x7F;
|
||||||
fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
|
fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
|
||||||
cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
|
cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (do_dts) {
|
if (do_dts && debug) {
|
||||||
unsigned int resolution;
|
unsigned int resolution;
|
||||||
|
|
||||||
if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
|
if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
|
||||||
|
@ -3526,7 +3528,6 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p
|
||||||
fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
|
fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
|
||||||
cpu, msr, tcc_activation_temp - dts, resolution);
|
cpu, msr, tcc_activation_temp - dts, resolution);
|
||||||
|
|
||||||
#ifdef THERM_DEBUG
|
|
||||||
if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
|
if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -3534,7 +3535,6 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p
|
||||||
dts2 = (msr >> 8) & 0x7F;
|
dts2 = (msr >> 8) & 0x7F;
|
||||||
fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
|
fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
|
||||||
cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
|
cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -4578,7 +4578,7 @@ int get_and_dump_counters(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_version() {
|
void print_version() {
|
||||||
fprintf(outf, "turbostat version 17.02.24"
|
fprintf(outf, "turbostat version 17.04.12"
|
||||||
" - Len Brown <lenb@kernel.org>\n");
|
" - Len Brown <lenb@kernel.org>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue