From: Shilpasri G Bhat <hidden> Date: 2016-01-01 22:22:48
In POWER8, OCC(On-Chip-Controller) can throttle the frequency of the
CPU when the chip crosses its thermal and power limits. Currently,
powernv-cpufreq driver detects and reports this event as a console
message. Some boxes may not sustain the max turbo frequency in all
conditions and can be throttled frequently. This can lead to the
flooding of console with throttle messages. So this patchset aims to
redesign the presentation of this event via sysfs counters and
tracepoints.
This patchset will add a perf trace point "power:powernv_throttle" and
sysfs throttle counter stats in /sys/devices/system/cpu/cpufreq/chipN.
Shilpasri G Bhat (2):
cpufreq: powernv/tracing: Add powernv_throttle tracepoint
cpufreq: powernv: Redesign the presentation of throttle notification
drivers/cpufreq/powernv-cpufreq.c | 247 +++++++++++++++++++++++++++++++-------
include/trace/events/power.h | 22 ++++
kernel/trace/power-traces.c | 1 +
3 files changed, 227 insertions(+), 43 deletions(-)
--
1.9.3
From: Shilpasri G Bhat <hidden> Date: 2016-01-01 22:22:59
This patch adds the powernv_throttle tracepoint to trace the CPU
frequency throttling event, which is used by the powernv-cpufreq
driver in POWER8.
Signed-off-by: Shilpasri G Bhat <redacted>
CC: Ingo Molnar <mingo@redhat.com>
CC: Steven Rostedt <rostedt@goodmis.org>
---
Changes from v1:
- Export the tracepoint
include/trace/events/power.h | 22 ++++++++++++++++++++++
kernel/trace/power-traces.c | 1 +
2 files changed, 23 insertions(+)
From: Shilpasri G Bhat <hidden> Date: 2016-01-01 22:23:09
Replace the throttling event console messages to perf trace point
"power:powernv_throttle" and throttle counter stats which are
exported in sysfs in /sys/devices/system/cpu/cpufreq/chipN. The
newly added sysfs files are as follows:
1)/sys/devices/system/cpu/cpufreq/chip0/throttle_frequencies
This gives the throttle stats for each of the available frequencies.
The throttle stat of a frequency is the total number of times the max
frequency is reduced to that frequency.
# cat /sys/devices/system/cpu/cpufreq/chip0/throttle_frequencies
4023000 0
3990000 0
3956000 1
3923000 0
3890000 0
3857000 2
3823000 0
3790000 0
3757000 2
3724000 1
3690000 1
...
2)/sys/devices/system/cpu/cpufreq/chip0/throttle_reasons
This directory contains throttle reason files. Each file gives the
total number of times the max frequency is throttled, except for
'throttle_reset', which gives the total number of times the max
frequency is unthrottled after being throttled.
# cd /sys/devices/system/cpu/cpufreq/chip0/throttle_reasons
# cat cpu_over_temperature
7
# cat occ_reset
0
# cat over_current
0
# cat power_cap
0
# cat power_supply_failure
0
# cat throttle_reset
7
3)/sys/devices/system/cpu/cpufreq/chip0/throttle_stat
This gives the total number of events of max frequency throttling to
lower frequencies in the turbo range of frequencies and the sub-turbo(at
and below nominal) range of frequencies.
# cat /sys/devices/system/cpu/cpufreq/chip0/throttle_stat
turbo 7
sub-turbo 0
Signed-off-by: Shilpasri G Bhat <redacted>
---
Changes from v1:
- Added a kobject to struct chip
- Grouped the throttle reasons under a separate attribute_group and
exported each reason as individual file.
- Moved the sysfs files from /sys/devices/system/node/nodeN to
/sys/devices/system/cpu/cpufreq/chipN
- As suggested by Paul Clarke replaced 'Nominal' with 'sub-turbo' and
char * throttle_reason[][30] by const char * const throttle_reason[].
- Modified the commit message.
drivers/cpufreq/powernv-cpufreq.c | 247 +++++++++++++++++++++++++++++++-------
1 file changed, 204 insertions(+), 43 deletions(-)
@@ -309,11 +335,11 @@ static inline unsigned int get_nominal_index(void)returnpowernv_pstate_info.max-powernv_pstate_info.nominal;}-staticvoidpowernv_cpufreq_throttle_check(void*data)+staticvoidpowernv_cpufreq_read_pmax(void*data){unsignedintcpu=smp_processor_id();unsignedlongpmsr;-intpmsr_pmax,i;+intpmsr_pmax,i,index;pmsr=get_pmspr(SPRN_PMSR);
@@ -321,28 +347,43 @@ static void powernv_cpufreq_throttle_check(void *data)if(chips[i].id==cpu_to_chip_id(cpu))break;-/* Check for Pmax Capping */pmsr_pmax=(s8)PMSR_MAX(pmsr);if(pmsr_pmax!=powernv_pstate_info.max){if(chips[i].throttled)-gotonext;+return;chips[i].throttled=true;-if(pmsr_pmax<powernv_pstate_info.nominal)-pr_crit("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",-cpu,chips[i].id,pmsr_pmax,+if(pmsr_pmax<powernv_pstate_info.nominal){+pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",+cpu,chips[i].id,pmsr_pmax,powernv_pstate_info.nominal);-else-pr_info("CPU %d on Chip %u has Pmax reduced below turbo frequency (%d < %d)\n",-cpu,chips[i].id,pmsr_pmax,-powernv_pstate_info.max);+chips[i].throt_nominal++;+}else{+chips[i].throt_turbo++;+}+index=powernv_pstate_info.max-pmsr_pmax;+if(index>=0&&index<powernv_pstate_info.nr_pstates)+chips[i].pstate_stat[index]++;+trace_powernv_throttle(chips[i].id,+throttle_reason[chips[i].throt_reason],+pmsr_pmax);}elseif(chips[i].throttled){chips[i].throttled=false;-pr_info("CPU %d on Chip %u has Pmax restored to %d\n",cpu,-chips[i].id,pmsr_pmax);+trace_powernv_throttle(chips[i].id,+throttle_reason[chips[i].throt_reason],+pmsr_pmax);}+}++staticvoidpowernv_cpufreq_throttle_check(void*data)+{+unsignedlongpmsr;++pmsr=get_pmspr(SPRN_PMSR);++/* Check for Pmax Capping */+powernv_cpufreq_read_pmax(NULL);/* Check if Psafe_mode_active is set in PMSR. */-next:if(pmsr&PMSR_PSAFE_ENABLE){throttled=true;pr_info("Pstate set to safe frequency\n");
@@ -356,7 +397,7 @@ next:if(throttled){pr_info("PMSR = %16lx\n",pmsr);-pr_crit("CPU Frequency could be throttled\n");+pr_warn("CPU Frequency could be throttled\n");}}
@@ -481,7 +513,7 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,*/if(!throttled){throttled=true;-pr_crit("CPU frequency is throttled for duration\n");+pr_warn("CPU frequency is throttled for duration\n");}break;
@@ -505,23 +537,19 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,return0;}-if(omsg.throttle_status&&-omsg.throttle_status<=OCC_MAX_THROTTLE_STATUS)-pr_info("OCC: Chip %u Pmax reduced due to %s\n",-(unsignedint)omsg.chip,-throttle_reason[omsg.throttle_status]);-elseif(!omsg.throttle_status)-pr_info("OCC: Chip %u %s\n",(unsignedint)omsg.chip,-throttle_reason[omsg.throttle_status]);-else-return0;-for(i=0;i<nr_chips;i++)-if(chips[i].id==omsg.chip){-if(!omsg.throttle_status)-chips[i].restore=true;-schedule_work(&chips[i].throttle);-}+if(chips[i].id==omsg.chip)+break;+if(omsg.throttle_status>=0&&+omsg.throttle_status<=OCC_MAX_THROTTLE_STATUS){+chips[i].reason[omsg.throttle_status]++;+chips[i].throt_reason=omsg.throttle_status;+}++if(!omsg.throttle_status)+chips[i].restore=true;++schedule_work(&chips[i].throttle);}return0;}
From: kbuild test robot <hidden> Date: 2016-01-02 02:10:36
Hi Shilpasri,
[auto build test WARNING on tip/perf/core]
[also build test WARNING on v4.4-rc7 next-20151231]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Shilpasri-G-Bhat/cpufreq-powernv-tracing-Add-powernv_throttle-tracepoint/20160102-062606
config: powerpc-allmodconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=powerpc
All warnings (new ones prefixed by >>):
drivers/cpufreq/powernv-cpufreq.c: In function 'occ_reset_show':
drivers/cpufreq/powernv-cpufreq.c:609:2: warning: ignoring return value of 'kstrtoint', declared with attribute warn_unused_result [-Wunused-result]
kstrtoint(kobj->name + 4, 0, &id); \
^
quoted
drivers/cpufreq/powernv-cpufreq.c:625:1: note: in expansion of macro 'define_throttle_reason_attr'
define_throttle_reason_attr(occ_reset, OCC_RESET_THROTTLE);
^
drivers/cpufreq/powernv-cpufreq.c: In function 'over_current_show':
drivers/cpufreq/powernv-cpufreq.c:609:2: warning: ignoring return value of 'kstrtoint', declared with attribute warn_unused_result [-Wunused-result]
kstrtoint(kobj->name + 4, 0, &id); \
^
drivers/cpufreq/powernv-cpufreq.c:624:1: note: in expansion of macro 'define_throttle_reason_attr'
define_throttle_reason_attr(over_current, OVERCURRENT);
^
drivers/cpufreq/powernv-cpufreq.c: In function 'power_supply_failure_show':
drivers/cpufreq/powernv-cpufreq.c:609:2: warning: ignoring return value of 'kstrtoint', declared with attribute warn_unused_result [-Wunused-result]
kstrtoint(kobj->name + 4, 0, &id); \
^
drivers/cpufreq/powernv-cpufreq.c:623:1: note: in expansion of macro 'define_throttle_reason_attr'
define_throttle_reason_attr(power_supply_failure, POWER_SUPPLY_FAILURE);
^
drivers/cpufreq/powernv-cpufreq.c: In function 'cpu_over_temperature_show':
drivers/cpufreq/powernv-cpufreq.c:609:2: warning: ignoring return value of 'kstrtoint', declared with attribute warn_unused_result [-Wunused-result]
kstrtoint(kobj->name + 4, 0, &id); \
^
drivers/cpufreq/powernv-cpufreq.c:622:1: note: in expansion of macro 'define_throttle_reason_attr'
define_throttle_reason_attr(cpu_over_temperature, CPU_OVERTEMP);
^
drivers/cpufreq/powernv-cpufreq.c: In function 'power_cap_show':
drivers/cpufreq/powernv-cpufreq.c:609:2: warning: ignoring return value of 'kstrtoint', declared with attribute warn_unused_result [-Wunused-result]
kstrtoint(kobj->name + 4, 0, &id); \
^
drivers/cpufreq/powernv-cpufreq.c:621:1: note: in expansion of macro 'define_throttle_reason_attr'
define_throttle_reason_attr(power_cap, POWERCAP);
^
drivers/cpufreq/powernv-cpufreq.c: In function 'throttle_reset_show':
drivers/cpufreq/powernv-cpufreq.c:609:2: warning: ignoring return value of 'kstrtoint', declared with attribute warn_unused_result [-Wunused-result]
kstrtoint(kobj->name + 4, 0, &id); \
^
drivers/cpufreq/powernv-cpufreq.c:620:1: note: in expansion of macro 'define_throttle_reason_attr'
define_throttle_reason_attr(throttle_reset, NO_THROTTLE);
^
drivers/cpufreq/powernv-cpufreq.c: In function 'throttle_stat_show':
drivers/cpufreq/powernv-cpufreq.c:589:2: warning: ignoring return value of 'kstrtoint', declared with attribute warn_unused_result [-Wunused-result]
kstrtoint(kobj->name + 4, 0, &id);
^
drivers/cpufreq/powernv-cpufreq.c: In function 'throttle_freq_show':
drivers/cpufreq/powernv-cpufreq.c:568:2: warning: ignoring return value of 'kstrtoint', declared with attribute warn_unused_result [-Wunused-result]
kstrtoint(kobj->name + 4, 0, &id);
^
vim +/define_throttle_reason_attr +625 drivers/cpufreq/powernv-cpufreq.c
603 #define define_throttle_reason_attr(attr_name, val) \
604 static ssize_t attr_name##_show(struct kobject *kobj, \
605 struct kobj_attribute *attr, char *buf) \
606 { \
607 int i, id; \
608 \
> 609 kstrtoint(kobj->name + 4, 0, &id); \
610 for (i = 0; i < nr_chips; i++) \
611 if (chips[i].id == id) \
612 break; \
613 \
614 return sprintf(buf, "%d\n", chips[i].reason[val]); \
615 } \
616 \
617 static struct kobj_attribute attr_##attr_name = \
618 __ATTR(attr_name, 0444, attr_name##_show, NULL)
619
620 define_throttle_reason_attr(throttle_reset, NO_THROTTLE);
621 define_throttle_reason_attr(power_cap, POWERCAP);
622 define_throttle_reason_attr(cpu_over_temperature, CPU_OVERTEMP);
623 define_throttle_reason_attr(power_supply_failure, POWER_SUPPLY_FAILURE);
624 define_throttle_reason_attr(over_current, OVERCURRENT);
> 625 define_throttle_reason_attr(occ_reset, OCC_RESET_THROTTLE);
626
627 static struct attribute *throttle_reason_attrs[] = {
628 &attr_throttle_reset.attr,
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
From: Shilpasri G Bhat <hidden> Date: 2016-01-04 09:25:45
In POWER8, OCC(On-Chip-Controller) can throttle the frequency of the
CPU when the chip crosses its thermal and power limits. Currently,
powernv-cpufreq driver detects and reports this event as a console
message. Some boxes may not sustain the max turbo frequency in all
conditions and can be throttled frequently. This can lead to the
flooding of console with throttle messages. So this patchset aims to
redesign the presentation of this event via sysfs counters and
tracepoints.
This patchset will add a perf trace point "power:powernv_throttle" and
sysfs throttle counter stats in /sys/devices/system/cpu/cpufreq/chipN.
Changes from v2:
- Fixed kbuild test warning.
drivers/cpufreq/powernv-cpufreq.c:609:2: warning: ignoring return
value of 'kstrtoint', declared with attribute warn_unused_result
[-Wunused-result]
Shilpasri G Bhat (2):
cpufreq: powernv/tracing: Add powernv_throttle tracepoint
cpufreq: powernv: Redesign the presentation of throttle notification
drivers/cpufreq/powernv-cpufreq.c | 256 +++++++++++++++++++++++++++++++-------
include/trace/events/power.h | 22 ++++
kernel/trace/power-traces.c | 1 +
3 files changed, 236 insertions(+), 43 deletions(-)
--
1.9.3
From: Shilpasri G Bhat <hidden> Date: 2016-01-04 09:25:59
This patch adds the powernv_throttle tracepoint to trace the CPU
frequency throttling event, which is used by the powernv-cpufreq
driver in POWER8.
Signed-off-by: Shilpasri G Bhat <redacted>
CC: Ingo Molnar <mingo@redhat.com>
CC: Steven Rostedt <rostedt@goodmis.org>
---
No changes from v2.
Changes from v1:
- Export the tracepoint
include/trace/events/power.h | 22 ++++++++++++++++++++++
kernel/trace/power-traces.c | 1 +
2 files changed, 23 insertions(+)
From: Shilpasri G Bhat <hidden> Date: 2016-01-04 09:26:31
Replace the throttling event console messages to perf trace point
"power:powernv_throttle" and throttle counter stats which are
exported in sysfs in /sys/devices/system/cpu/cpufreq/chipN. The
newly added sysfs files are as follows:
1)/sys/devices/system/cpu/cpufreq/chip0/throttle_frequencies
This gives the throttle stats for each of the available frequencies.
The throttle stat of a frequency is the total number of times the max
frequency is reduced to that frequency.
# cat /sys/devices/system/cpu/cpufreq/chip0/throttle_frequencies
4023000 0
3990000 0
3956000 1
3923000 0
3890000 0
3857000 2
3823000 0
3790000 0
3757000 2
3724000 1
3690000 1
...
2)/sys/devices/system/cpu/cpufreq/chip0/throttle_reasons
This directory contains throttle reason files. Each file gives the
total number of times the max frequency is throttled, except for
'throttle_reset', which gives the total number of times the max
frequency is unthrottled after being throttled.
# cd /sys/devices/system/cpu/cpufreq/chip0/throttle_reasons
# cat cpu_over_temperature
7
# cat occ_reset
0
# cat over_current
0
# cat power_cap
0
# cat power_supply_failure
0
# cat throttle_reset
7
3)/sys/devices/system/cpu/cpufreq/chip0/throttle_stat
This gives the total number of events of max frequency throttling to
lower frequencies in the turbo range of frequencies and the sub-turbo(at
and below nominal) range of frequencies.
# cat /sys/devices/system/cpu/cpufreq/chip0/throttle_stat
turbo 7
sub-turbo 0
Signed-off-by: Shilpasri G Bhat <redacted>
---
Changes from v2:
- Fixed kbuild test warning.
drivers/cpufreq/powernv-cpufreq.c:609:2: warning: ignoring return
value of 'kstrtoint', declared with attribute warn_unused_result
[-Wunused-result]
Changes from v1:
- Added a kobject to struct chip
- Grouped the throttle reasons under a separate attribute_group and
exported each reason as individual file.
- Moved the sysfs files from /sys/devices/system/node/nodeN to
/sys/devices/system/cpu/cpufreq/chipN
- As suggested by Paul Clarke replaced 'Nominal' with 'sub-turbo' and
char * throttle_reason[][30] by const char * const throttle_reason[].
- Modified the commit message.
drivers/cpufreq/powernv-cpufreq.c | 256 +++++++++++++++++++++++++++++++-------
1 file changed, 213 insertions(+), 43 deletions(-)
@@ -309,11 +335,11 @@ static inline unsigned int get_nominal_index(void)returnpowernv_pstate_info.max-powernv_pstate_info.nominal;}-staticvoidpowernv_cpufreq_throttle_check(void*data)+staticvoidpowernv_cpufreq_read_pmax(void*data){unsignedintcpu=smp_processor_id();unsignedlongpmsr;-intpmsr_pmax,i;+intpmsr_pmax,i,index;pmsr=get_pmspr(SPRN_PMSR);
@@ -321,28 +347,43 @@ static void powernv_cpufreq_throttle_check(void *data)if(chips[i].id==cpu_to_chip_id(cpu))break;-/* Check for Pmax Capping */pmsr_pmax=(s8)PMSR_MAX(pmsr);if(pmsr_pmax!=powernv_pstate_info.max){if(chips[i].throttled)-gotonext;+return;chips[i].throttled=true;-if(pmsr_pmax<powernv_pstate_info.nominal)-pr_crit("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",-cpu,chips[i].id,pmsr_pmax,+if(pmsr_pmax<powernv_pstate_info.nominal){+pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",+cpu,chips[i].id,pmsr_pmax,powernv_pstate_info.nominal);-else-pr_info("CPU %d on Chip %u has Pmax reduced below turbo frequency (%d < %d)\n",-cpu,chips[i].id,pmsr_pmax,-powernv_pstate_info.max);+chips[i].throt_nominal++;+}else{+chips[i].throt_turbo++;+}+index=powernv_pstate_info.max-pmsr_pmax;+if(index>=0&&index<powernv_pstate_info.nr_pstates)+chips[i].pstate_stat[index]++;+trace_powernv_throttle(chips[i].id,+throttle_reason[chips[i].throt_reason],+pmsr_pmax);}elseif(chips[i].throttled){chips[i].throttled=false;-pr_info("CPU %d on Chip %u has Pmax restored to %d\n",cpu,-chips[i].id,pmsr_pmax);+trace_powernv_throttle(chips[i].id,+throttle_reason[chips[i].throt_reason],+pmsr_pmax);}+}++staticvoidpowernv_cpufreq_throttle_check(void*data)+{+unsignedlongpmsr;++pmsr=get_pmspr(SPRN_PMSR);++/* Check for Pmax Capping */+powernv_cpufreq_read_pmax(NULL);/* Check if Psafe_mode_active is set in PMSR. */-next:if(pmsr&PMSR_PSAFE_ENABLE){throttled=true;pr_info("Pstate set to safe frequency\n");
@@ -356,7 +397,7 @@ next:if(throttled){pr_info("PMSR = %16lx\n",pmsr);-pr_crit("CPU Frequency could be throttled\n");+pr_warn("CPU Frequency could be throttled\n");}}
@@ -481,7 +513,7 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,*/if(!throttled){throttled=true;-pr_crit("CPU frequency is throttled for duration\n");+pr_warn("CPU frequency is throttled for duration\n");}break;
@@ -505,23 +537,19 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,return0;}-if(omsg.throttle_status&&-omsg.throttle_status<=OCC_MAX_THROTTLE_STATUS)-pr_info("OCC: Chip %u Pmax reduced due to %s\n",-(unsignedint)omsg.chip,-throttle_reason[omsg.throttle_status]);-elseif(!omsg.throttle_status)-pr_info("OCC: Chip %u %s\n",(unsignedint)omsg.chip,-throttle_reason[omsg.throttle_status]);-else-return0;-for(i=0;i<nr_chips;i++)-if(chips[i].id==omsg.chip){-if(!omsg.throttle_status)-chips[i].restore=true;-schedule_work(&chips[i].throttle);-}+if(chips[i].id==omsg.chip)+break;+if(omsg.throttle_status>=0&&+omsg.throttle_status<=OCC_MAX_THROTTLE_STATUS){+chips[i].reason[omsg.throttle_status]++;+chips[i].throt_reason=omsg.throttle_status;+}++if(!omsg.throttle_status)+chips[i].restore=true;++schedule_work(&chips[i].throttle);}return0;}
From: Stewart Smith <hidden> Date: 2016-01-06 06:52:26
Shilpasri G Bhat [off-list ref] writes:
In POWER8, OCC(On-Chip-Controller) can throttle the frequency of the
CPU when the chip crosses its thermal and power limits. Currently,
powernv-cpufreq driver detects and reports this event as a console
message. Some boxes may not sustain the max turbo frequency in all
conditions and can be throttled frequently. This can lead to the
flooding of console with throttle messages. So this patchset aims to
redesign the presentation of this event via sysfs counters and
tracepoints.
This likely should CC stable@ as we have seen this on some machines, at
least in the lab.
--
Stewart Smith
OPAL Architect, IBM.
From: Shilpasri G Bhat <hidden> Date: 2016-01-11 20:56:46
In POWER8, OCC(On-Chip-Controller) can throttle the frequency of the
CPU when the chip crosses its thermal and power limits. Currently,
powernv-cpufreq driver detects and reports this event as a console
message. Some machines may not sustain the max turbo frequency in all
conditions and can be throttled frequently. This can lead to the
flooding of console with throttle messages. So this patchset aims to
redesign the presentation of this event via sysfs counters and
tracepoints.
Patches [2] to [4] will add a perf trace point "power:powernv_throttle" and
sysfs throttle counter stats in /sys/devices/system/cpu/cpufreq/chipN.
Patch [1] solves a bug in powernv_cpufreq_throttle_check(), which calls in to
cpu_to_chip_id() in hot path which reads DT every time to find the chip id.
Changes from v3:
- Add a fix to replace cpu_to_chip_id() with simpler PIR shift to obtain the
chip id.
- Break patch2 in to two patches separating the tracepoint and sysfs attribute
changes.
Changes from v2:
- Fixed kbuild test warning.
drivers/cpufreq/powernv-cpufreq.c:609:2: warning: ignoring return
value of 'kstrtoint', declared with attribute warn_unused_result
[-Wunused-result]
Shilpasri G Bhat (4):
cpufreq: powernv: Remove cpu_to_chip_id() from hot-path
cpufreq: powernv/tracing: Add powernv_throttle tracepoint
cpufreq: powernv: Add a trace print for the throttle event
cpufreq: powernv: Add sysfs attributes to show throttle stats
drivers/cpufreq/powernv-cpufreq.c | 279 +++++++++++++++++++++++++++++++-------
include/trace/events/power.h | 22 +++
kernel/trace/power-traces.c | 1 +
3 files changed, 250 insertions(+), 52 deletions(-)
--
1.9.1
From: Shilpasri G Bhat <hidden> Date: 2016-01-11 20:57:03
This patch adds the powernv_throttle tracepoint to trace the CPU
frequency throttling event, which is used by the powernv-cpufreq
driver in POWER8.
Signed-off-by: Shilpasri G Bhat <redacted>
CC: Ingo Molnar <mingo@redhat.com>
CC: Steven Rostedt <rostedt@goodmis.org>
---
No changes from v2 and v3.
include/trace/events/power.h | 22 ++++++++++++++++++++++
kernel/trace/power-traces.c | 1 +
2 files changed, 23 insertions(+)
From: Shilpasri G Bhat <hidden> Date: 2016-01-11 20:57:10
Record the throttle event with a trace print replacing the printk,
except for events like throttling below nominal and occ reset
event which print a warning message.
Signed-off-by: Shilpasri G Bhat <redacted>
---
Changes from v3:
- Separate this patch to contain trace_point changes
- Move struct chip member 'restore' of type bool above 'mask' to reduce
structure padding.
No changes from v2.
Changes from v1:
- As suggested by Paul Clarke replaced char * throttle_reason[][30] by
const char * const throttle_reason[].
drivers/cpufreq/powernv-cpufreq.c | 95 ++++++++++++++++++++-------------------
1 file changed, 49 insertions(+), 46 deletions(-)
@@ -310,41 +321,49 @@ static inline unsigned int get_nominal_index(void)returnpowernv_pstate_info.max-powernv_pstate_info.nominal;}-staticvoidpowernv_cpufreq_throttle_check(void*data)+staticvoidpowernv_cpufreq_check_pmax(void){unsignedintcpu=smp_processor_id();unsignedintchip_id=pir_to_chip_id(hard_smp_processor_id());-unsignedlongpmsr;intpmsr_pmax,i;-pmsr=get_pmspr(SPRN_PMSR);+pmsr_pmax=(s8)PMSR_MAX(get_pmspr(SPRN_PMSR));for(i=0;i<nr_chips;i++)if(chips[i].id==chip_id)break;-/* Check for Pmax Capping */-pmsr_pmax=(s8)PMSR_MAX(pmsr);if(pmsr_pmax!=powernv_pstate_info.max){if(chips[i].throttled)-gotonext;+return;+chips[i].throttled=true;if(pmsr_pmax<powernv_pstate_info.nominal)-pr_crit("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",-cpu,chips[i].id,pmsr_pmax,-powernv_pstate_info.nominal);-else-pr_info("CPU %d on Chip %u has Pmax reduced below turbo frequency (%d < %d)\n",-cpu,chips[i].id,pmsr_pmax,-powernv_pstate_info.max);+pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",+cpu,chips[i].id,pmsr_pmax,+powernv_pstate_info.nominal);++trace_powernv_throttle(chips[i].id,+throttle_reason[chips[i].throt_reason],+pmsr_pmax);}elseif(chips[i].throttled){chips[i].throttled=false;-pr_info("CPU %d on Chip %u has Pmax restored to %d\n",cpu,-chips[i].id,pmsr_pmax);+trace_powernv_throttle(chips[i].id,+throttle_reason[chips[i].throt_reason],+pmsr_pmax);}+}++staticvoidpowernv_cpufreq_throttle_check(void*data)+{+unsignedlongpmsr;++pmsr=get_pmspr(SPRN_PMSR);++/* Check for Pmax Capping */+powernv_cpufreq_check_pmax();/* Check if Psafe_mode_active is set in PMSR. */-next:if(pmsr&PMSR_PSAFE_ENABLE){throttled=true;pr_info("Pstate set to safe frequency\n");
@@ -358,7 +377,7 @@ next:if(throttled){pr_info("PMSR = %16lx\n",pmsr);-pr_crit("CPU Frequency could be throttled\n");+pr_warn("CPU Frequency could be throttled\n");}}
@@ -483,7 +493,7 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,*/if(!throttled){throttled=true;-pr_crit("CPU frequency is throttled for duration\n");+pr_warn("CPU frequency is throttled for duration\n");}break;
@@ -507,23 +517,18 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,return0;}-if(omsg.throttle_status&&+for(i=0;i<nr_chips;i++)+if(chips[i].id==omsg.chip)+break;++if(omsg.throttle_status>=0&&omsg.throttle_status<=OCC_MAX_THROTTLE_STATUS)-pr_info("OCC: Chip %u Pmax reduced due to %s\n",-(unsignedint)omsg.chip,-throttle_reason[omsg.throttle_status]);-elseif(!omsg.throttle_status)-pr_info("OCC: Chip %u %s\n",(unsignedint)omsg.chip,-throttle_reason[omsg.throttle_status]);-else-return0;+chips[i].throt_reason=omsg.throttle_status;-for(i=0;i<nr_chips;i++)-if(chips[i].id==omsg.chip){-if(!omsg.throttle_status)-chips[i].restore=true;-schedule_work(&chips[i].throttle);-}+if(!omsg.throttle_status)+chips[i].restore=true;++schedule_work(&chips[i].throttle);}return0;}
@@ -569,16 +574,14 @@ static int init_chip_info(void)}}-chips=kmalloc_array(nr_chips,sizeof(structchip),GFP_KERNEL);+chips=kcalloc(nr_chips,sizeof(structchip),GFP_KERNEL);if(!chips)return-ENOMEM;for(i=0;i<nr_chips;i++){chips[i].id=chip[i];-chips[i].throttled=false;cpumask_copy(&chips[i].mask,cpumask_of_node(chip[i]));INIT_WORK(&chips[i].throttle,powernv_cpufreq_work_fn);-chips[i].restore=false;}return0;
From: Shilpasri G Bhat <hidden> Date: 2016-01-11 20:57:18
Create sysfs attributes to export throttle information in
/sys/devices/system/cpu/cpufreq/chipN. The newly added sysfs files are as
follows:
1)/sys/devices/system/cpu/cpufreq/chip0/throttle_frequencies
This gives the throttle stats for each of the available frequencies.
The throttle stat of a frequency is the total number of times the max
frequency is reduced to that frequency.
# cat /sys/devices/system/cpu/cpufreq/chip0/throttle_frequencies
4023000 0
3990000 0
3956000 1
3923000 0
3890000 0
3857000 2
3823000 0
3790000 0
3757000 2
3724000 1
3690000 1
...
2)/sys/devices/system/cpu/cpufreq/chip0/throttle_reasons
This directory contains throttle reason files. Each file gives the
total number of times the max frequency is throttled, except for
'throttle_reset', which gives the total number of times the max
frequency is unthrottled after being throttled.
# cd /sys/devices/system/cpu/cpufreq/chip0/throttle_reasons
# cat cpu_over_temperature
7
# cat occ_reset
0
# cat over_current
0
# cat power_cap
0
# cat power_supply_failure
0
# cat throttle_reset
7
3)/sys/devices/system/cpu/cpufreq/chip0/throttle_stat
This gives the total number of events of max frequency throttling to
lower frequencies in the turbo range of frequencies and the sub-turbo(at
and below nominal) range of frequencies.
# cat /sys/devices/system/cpu/cpufreq/chip0/throttle_stat
turbo 7
sub-turbo 0
Signed-off-by: Shilpasri G Bhat <redacted>
---
Changes from v3:
- Seperate the patch to contain only the throttle sysfs attribute changes.
- Add helper inline function get_chip_index()
Changes from v2:
- Fixed kbuild test warning.
drivers/cpufreq/powernv-cpufreq.c:609:2: warning: ignoring return
value of 'kstrtoint', declared with attribute warn_unused_result
[-Wunused-result]
Changes from v1:
- Added a kobject to struct chip
- Grouped the throttle reasons under a separate attribute_group and
exported each reason as individual file.
- Moved the sysfs files from /sys/devices/system/node/nodeN to
/sys/devices/system/cpu/cpufreq/chipN
- As suggested by Paul Clarke replaced 'Nominal' with 'sub-turbo'.
- Modified the commit message.
drivers/cpufreq/powernv-cpufreq.c | 177 +++++++++++++++++++++++++++++++++++++-
1 file changed, 173 insertions(+), 4 deletions(-)
From: Shilpasri G Bhat <hidden> Date: 2016-01-11 20:58:34
cpu_to_chip_id() does a DT walk through to find out the chip id by taking a
contended device tree lock. This adds an unnecessary overhead in a hot-path.
So instead of cpu_to_chip_id() use PIR of the cpu to find the chip id.
Reported-by: Anton Blanchard <redacted>
Signed-off-by: Shilpasri G Bhat <redacted>
---
drivers/cpufreq/powernv-cpufreq.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
On Mon, Jan 11, 2016 at 02:54:36PM -0600, Shilpasri G Bhat wrote:
In POWER8, OCC(On-Chip-Controller) can throttle the frequency of the
CPU when the chip crosses its thermal and power limits. Currently,
powernv-cpufreq driver detects and reports this event as a console
message. Some machines may not sustain the max turbo frequency in all
conditions and can be throttled frequently. This can lead to the
flooding of console with throttle messages. So this patchset aims to
redesign the presentation of this event via sysfs counters and
tracepoints.
Patches [2] to [4] will add a perf trace point "power:powernv_throttle" and
sysfs throttle counter stats in /sys/devices/system/cpu/cpufreq/chipN.
Patch [1] solves a bug in powernv_cpufreq_throttle_check(), which calls in to
cpu_to_chip_id() in hot path which reads DT every time to find the chip id.
<formletter>
This is not the correct way to submit patches for inclusion in the
stable kernel tree. Please read Documentation/stable_kernel_rules.txt
for how to do this properly.
</formletter>
On Mon, Jan 11, 2016 at 02:54:36PM -0600, Shilpasri G Bhat wrote:
quoted
In POWER8, OCC(On-Chip-Controller) can throttle the frequency of the
CPU when the chip crosses its thermal and power limits. Currently,
powernv-cpufreq driver detects and reports this event as a console
message. Some machines may not sustain the max turbo frequency in all
conditions and can be throttled frequently. This can lead to the
flooding of console with throttle messages. So this patchset aims to
redesign the presentation of this event via sysfs counters and
tracepoints.
Patches [2] to [4] will add a perf trace point "power:powernv_throttle" and
sysfs throttle counter stats in /sys/devices/system/cpu/cpufreq/chipN.
Patch [1] solves a bug in powernv_cpufreq_throttle_check(), which calls in to
cpu_to_chip_id() in hot path which reads DT every time to find the chip id.
<formletter>
This is not the correct way to submit patches for inclusion in the
stable kernel tree. Please read Documentation/stable_kernel_rules.txt
for how to do this properly.
</formletter>
Also you shouldn't use --in-reply-to for the new versions of a
multiple patch series. Just use a new thread.
--
viresh