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

cpufreq: powernv: Report cpu frequency throttling

The power and thermal safety of the system is taken care by an
On-Chip-Controller (OCC) which is real-time subsystem embedded within
the POWER8 processor. OCC continuously monitors the memory and core
temperature, the total system power, state of power supply and fan.

The cpu frequency can be throttled by OCC for the following reasons:
1)If a processor crosses its power and temperature limit then OCC will
lower its Pmax to reduce the frequency and voltage.
2)If OCC crashes then the system is forced to Psafe frequency.
3)If OCC fails to recover then the kernel is not allowed to do any
further frequency changes and the chip will remain in Psafe.

The user can see a drop in performance when frequency is throttled and
is unaware of throttling. So detect and report such a condition, so
the user can check the OCC status to reboot the system or check for
power supply or fan failures.

The current status of the core is read from Power Management Status
Register(PMSR) to check if any of the throttling condition is occurred
and the appropriate throttling message is reported.

Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Shilpasri G Bhat and committed by
Rafael J. Wysocki
09a972d1 2f249358

+46 -1
+46 -1
drivers/cpufreq/powernv-cpufreq.c
··· 34 34 #include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */ 35 35 36 36 #define POWERNV_MAX_PSTATES 256 37 + #define PMSR_PSAFE_ENABLE (1UL << 30) 38 + #define PMSR_SPR_EM_DISABLE (1UL << 31) 39 + #define PMSR_MAX(x) ((x >> 32) & 0xFF) 40 + #define PMSR_LP(x) ((x >> 48) & 0xFF) 37 41 38 42 static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; 39 - static bool rebooting; 43 + static bool rebooting, throttled; 40 44 41 45 /* 42 46 * Note: The set of pstates consists of contiguous integers, the ··· 298 294 return powernv_pstate_info.max - powernv_pstate_info.nominal; 299 295 } 300 296 297 + static void powernv_cpufreq_throttle_check(unsigned int cpu) 298 + { 299 + unsigned long pmsr; 300 + int pmsr_pmax, pmsr_lp; 301 + 302 + pmsr = get_pmspr(SPRN_PMSR); 303 + 304 + /* Check for Pmax Capping */ 305 + pmsr_pmax = (s8)PMSR_MAX(pmsr); 306 + if (pmsr_pmax != powernv_pstate_info.max) { 307 + throttled = true; 308 + pr_info("CPU %d Pmax is reduced to %d\n", cpu, pmsr_pmax); 309 + pr_info("Max allowed Pstate is capped\n"); 310 + } 311 + 312 + /* 313 + * Check for Psafe by reading LocalPstate 314 + * or check if Psafe_mode_active is set in PMSR. 315 + */ 316 + pmsr_lp = (s8)PMSR_LP(pmsr); 317 + if ((pmsr_lp < powernv_pstate_info.min) || 318 + (pmsr & PMSR_PSAFE_ENABLE)) { 319 + throttled = true; 320 + pr_info("Pstate set to safe frequency\n"); 321 + } 322 + 323 + /* Check if SPR_EM_DISABLE is set in PMSR */ 324 + if (pmsr & PMSR_SPR_EM_DISABLE) { 325 + throttled = true; 326 + pr_info("Frequency Control disabled from OS\n"); 327 + } 328 + 329 + if (throttled) { 330 + pr_info("PMSR = %16lx\n", pmsr); 331 + pr_crit("CPU Frequency could be throttled\n"); 332 + } 333 + } 334 + 301 335 /* 302 336 * powernv_cpufreq_target_index: Sets the frequency corresponding to 303 337 * the cpufreq table entry indexed by new_index on the cpus in the ··· 348 306 349 307 if (unlikely(rebooting) && new_index != get_nominal_index()) 350 308 return 0; 309 + 310 + if (!throttled) 311 + powernv_cpufreq_throttle_check(smp_processor_id()); 351 312 352 313 freq_data.pstate_id = powernv_freqs[new_index].driver_data; 353 314