aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/powernv-cpufreq.c
diff options
context:
space:
mode:
authorShilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>2016-03-22 09:27:09 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-03-22 18:11:18 -0400
commit1b0289848d5dcea74a6e5115d6c9892b0dbe9c8f (patch)
tree9c5e57f419938d5acc48ad5c63d275d07e20774d /drivers/cpufreq/powernv-cpufreq.c
parentac13b9967de7eeb7746f6533673e4dec94933bc9 (diff)
cpufreq: powernv: Add sysfs attributes to show throttle stats
Create sysfs attributes to export throttle information in /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats directory. The newly added sysfs files are as follows: 1)/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/turbo_stat 2)/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/sub-turbo_stat 3)/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/unthrottle 4)/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/powercap 5)/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/overtemp 6)/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/supply_fault 7)/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/overcurrent 8)/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/occ_reset Detailed explanation of each attribute is added to Documentation/ABI/testing/sysfs-devices-system-cpu Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/powernv-cpufreq.c')
-rw-r--r--drivers/cpufreq/powernv-cpufreq.c74
1 files changed, 72 insertions, 2 deletions
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index a00bcc2cef09..39ac78c94be0 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -54,6 +54,16 @@ static const char * const throttle_reason[] = {
54 "OCC Reset" 54 "OCC Reset"
55}; 55};
56 56
57enum throttle_reason_type {
58 NO_THROTTLE = 0,
59 POWERCAP,
60 CPU_OVERTEMP,
61 POWER_SUPPLY_FAILURE,
62 OVERCURRENT,
63 OCC_RESET_THROTTLE,
64 OCC_MAX_REASON
65};
66
57static struct chip { 67static struct chip {
58 unsigned int id; 68 unsigned int id;
59 bool throttled; 69 bool throttled;
@@ -61,6 +71,9 @@ static struct chip {
61 u8 throttle_reason; 71 u8 throttle_reason;
62 cpumask_t mask; 72 cpumask_t mask;
63 struct work_struct throttle; 73 struct work_struct throttle;
74 int throttle_turbo;
75 int throttle_sub_turbo;
76 int reason[OCC_MAX_REASON];
64} *chips; 77} *chips;
65 78
66static int nr_chips; 79static int nr_chips;
@@ -196,6 +209,42 @@ static struct freq_attr *powernv_cpu_freq_attr[] = {
196 NULL, 209 NULL,
197}; 210};
198 211
212#define throttle_attr(name, member) \
213static ssize_t name##_show(struct cpufreq_policy *policy, char *buf) \
214{ \
215 struct chip *chip = per_cpu(chip_info, policy->cpu); \
216 \
217 return sprintf(buf, "%u\n", chip->member); \
218} \
219 \
220static struct freq_attr throttle_attr_##name = __ATTR_RO(name) \
221
222throttle_attr(unthrottle, reason[NO_THROTTLE]);
223throttle_attr(powercap, reason[POWERCAP]);
224throttle_attr(overtemp, reason[CPU_OVERTEMP]);
225throttle_attr(supply_fault, reason[POWER_SUPPLY_FAILURE]);
226throttle_attr(overcurrent, reason[OVERCURRENT]);
227throttle_attr(occ_reset, reason[OCC_RESET_THROTTLE]);
228throttle_attr(turbo_stat, throttle_turbo);
229throttle_attr(sub_turbo_stat, throttle_sub_turbo);
230
231static struct attribute *throttle_attrs[] = {
232 &throttle_attr_unthrottle.attr,
233 &throttle_attr_powercap.attr,
234 &throttle_attr_overtemp.attr,
235 &throttle_attr_supply_fault.attr,
236 &throttle_attr_overcurrent.attr,
237 &throttle_attr_occ_reset.attr,
238 &throttle_attr_turbo_stat.attr,
239 &throttle_attr_sub_turbo_stat.attr,
240 NULL,
241};
242
243static const struct attribute_group throttle_attr_grp = {
244 .name = "throttle_stats",
245 .attrs = throttle_attrs,
246};
247
199/* Helper routines */ 248/* Helper routines */
200 249
201/* Access helpers to power mgt SPR */ 250/* Access helpers to power mgt SPR */
@@ -338,10 +387,14 @@ static void powernv_cpufreq_throttle_check(void *data)
338 if (chip->throttled) 387 if (chip->throttled)
339 goto next; 388 goto next;
340 chip->throttled = true; 389 chip->throttled = true;
341 if (pmsr_pmax < powernv_pstate_info.nominal) 390 if (pmsr_pmax < powernv_pstate_info.nominal) {
342 pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n", 391 pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",
343 cpu, chip->id, pmsr_pmax, 392 cpu, chip->id, pmsr_pmax,
344 powernv_pstate_info.nominal); 393 powernv_pstate_info.nominal);
394 chip->throttle_sub_turbo++;
395 } else {
396 chip->throttle_turbo++;
397 }
345 trace_powernv_throttle(chip->id, 398 trace_powernv_throttle(chip->id,
346 throttle_reason[chip->throttle_reason], 399 throttle_reason[chip->throttle_reason],
347 pmsr_pmax); 400 pmsr_pmax);
@@ -408,6 +461,21 @@ static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy)
408 for (i = 0; i < threads_per_core; i++) 461 for (i = 0; i < threads_per_core; i++)
409 cpumask_set_cpu(base + i, policy->cpus); 462 cpumask_set_cpu(base + i, policy->cpus);
410 463
464 if (!policy->driver_data) {
465 int ret;
466
467 ret = sysfs_create_group(&policy->kobj, &throttle_attr_grp);
468 if (ret) {
469 pr_info("Failed to create throttle stats directory for cpu %d\n",
470 policy->cpu);
471 return ret;
472 }
473 /*
474 * policy->driver_data is used as a flag for one-time
475 * creation of throttle sysfs files.
476 */
477 policy->driver_data = policy;
478 }
411 return cpufreq_table_validate_and_show(policy, powernv_freqs); 479 return cpufreq_table_validate_and_show(policy, powernv_freqs);
412} 480}
413 481
@@ -514,8 +582,10 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,
514 break; 582 break;
515 583
516 if (omsg.throttle_status >= 0 && 584 if (omsg.throttle_status >= 0 &&
517 omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS) 585 omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS) {
518 chips[i].throttle_reason = omsg.throttle_status; 586 chips[i].throttle_reason = omsg.throttle_status;
587 chips[i].reason[omsg.throttle_status]++;
588 }
519 589
520 if (!omsg.throttle_status) 590 if (!omsg.throttle_status)
521 chips[i].restore = true; 591 chips[i].restore = true;