* [PATCH v7 6/6] cpufreq: powernv: Add sysfs attributes to show throttle stats
[not found] <1453965941-7363-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com>
@ 2016-01-28 7:25 ` Shilpasri G Bhat
2016-01-28 8:40 ` Viresh Kumar
[not found] ` <1453965941-7363-7-git-send-email-shilpa.bhat-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
0 siblings, 2 replies; 7+ messages in thread
From: Shilpasri G Bhat @ 2016-01-28 7:25 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel
Cc: rjw, viresh.kumar, linux-pm, pc, anton, ego, shreyas, bsingharora,
mpe, Shilpasri G Bhat, linux-api
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
'unthrottle_count', 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 unthrottle_count
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 <shilpa.bhat@linux.vnet.ibm.com>
Cc: linux-api@vger.kernel.org
---
Changes from v6:
- Rename struct chip members 'throt_{nominal/turbo}' to throttle_*
- Rename sysfs throttle_reason attribute 'throttle_reset' to
'unthrottle_count'
- Add sysfs attribute details in
Documentation/ABI/testing/sysfs-devices-system-cpu
- Add helper routine get_chip_index_from_kobj() for throttle sysfs
attribute show() to get chip index from kobject.
- Add the chip id in the pr_warn_once
No changes from v5.
Changes from v4:
- Taken care of Gautham's comments to use inline get_chip_index()
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'.
Documentation/ABI/testing/sysfs-devices-system-cpu | 45 +++++
drivers/cpufreq/powernv-cpufreq.c | 205 ++++++++++++++++++++-
2 files changed, 241 insertions(+), 9 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index b683e8e..dea4620 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -271,3 +271,48 @@ Description: Parameters for the CPU cache attributes
- WriteBack: data is written only to the cache line and
the modified cache line is written to main
memory only when it is replaced
+
+What: /sys/devices/system/cpu/cpufreq/chip*/throttle_stats
+Date: Jan 2016
+Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
+ Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
+Description: CPU Frequency throttle stat for the chip
+
+ This attribute gives the total number of events of max-frequency
+ throttling to any lower frequency in the turbo(above nominal) and
+ the sub-turbo (at and below nominal) range of frequencies.
+
+
+What: /sys/devices/system/cpu/cpufreq/chip*/throttle_frequencies
+Date: Jan 2016
+Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
+ Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
+Description: CPU Frequency throttle stat for all available frequencies in the chip
+
+ This attribute 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.
+
+What: /sys/devices/system/cpu/cpufreq/chip*/throttle_reasons/<reason_attributes>
+Date: Jan 2016
+Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
+ Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
+Description: CPU Frequency throttle reason stat for the chip
+
+ This directory contains throttle reason files. Each file gives
+ the total number of times the max frequency is throttled, except
+ for 'unthrottle_count', which gives the total number of times
+ the max frequency is unthrottled after being throttled. Below
+ are the reason attributes.
+
+ cpu_over_temperature: Throttled due to cpu over temperature
+
+ occ_reset: Throttled due to reset of OCC
+
+ over_current: Throttled due to over current
+
+ power_cap: Throttled due to power capping
+
+ power_supply_failure: Throttled due to power supply failure
+
+ unthrottle_count: Unthrottled from any of the above reasons.
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index 1bbc10a..b647941 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -55,6 +55,16 @@ static const char * const throttle_reason[] = {
"OCC Reset"
};
+enum throttle_reason_type {
+ NO_THROTTLE = 0,
+ POWERCAP,
+ CPU_OVERTEMP,
+ POWER_SUPPLY_FAILURE,
+ OVERCURRENT,
+ OCC_RESET_THROTTLE,
+ OCC_MAX_REASON
+};
+
static struct chip {
unsigned int id;
bool throttled;
@@ -62,6 +72,11 @@ static struct chip {
u8 throttle_reason;
cpumask_t mask;
struct work_struct throttle;
+ int throttle_turbo;
+ int throttle_nominal;
+ int reason[OCC_MAX_REASON];
+ int *pstate_stat;
+ struct kobject *kobj;
} *chips;
static int nr_chips;
@@ -196,6 +211,126 @@ static struct freq_attr *powernv_cpu_freq_attr[] = {
NULL,
};
+static inline int get_chip_index(unsigned int id)
+{
+ int i;
+
+ for (i = 0; i < nr_chips; i++)
+ if (chips[i].id == id)
+ return i;
+
+ return -EINVAL;
+}
+
+static inline int get_chip_index_from_kobj(struct kobject *kobj)
+{
+ int ret, id;
+ int len = strlen("chip");
+
+ ret = kstrtoint(kobj->name + len, 0, &id);
+ if (ret)
+ return ret;
+
+ ret = get_chip_index(id);
+ if (ret < 0)
+ pr_warn_once("%s Matching chip-id not found %d\n", __func__,
+ id);
+ return ret;
+}
+
+static ssize_t throttle_freq_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ int i, count = 0, id;
+
+ id = get_chip_index_from_kobj(kobj);
+ if (id < 0)
+ return id;
+
+ for (i = 0; i < powernv_pstate_info.nr_pstates; i++)
+ count += sprintf(&buf[count], "%d %d\n",
+ powernv_freqs[i].frequency,
+ chips[id].pstate_stat[i]);
+
+ return count;
+}
+
+static struct kobj_attribute attr_throttle_frequencies =
+__ATTR(throttle_frequencies, 0444, throttle_freq_show, NULL);
+
+static ssize_t throttle_stat_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ int id, count = 0;
+
+ id = get_chip_index_from_kobj(kobj);
+ if (id < 0)
+ return id;
+
+ count += sprintf(&buf[count], "turbo %d\n", chips[id].throttle_turbo);
+ count += sprintf(&buf[count], "sub-turbo %d\n",
+ chips[id].throttle_nominal);
+
+ return count;
+}
+
+static struct kobj_attribute attr_throttle_stat =
+__ATTR(throttle_stat, 0444, throttle_stat_show, NULL);
+
+#define define_throttle_reason_attr(attr_name, val) \
+static ssize_t attr_name##_show(struct kobject *kobj, \
+ struct kobj_attribute *attr, char *buf) \
+{ \
+ int id; \
+ \
+ id = get_chip_index_from_kobj(kobj); \
+ if (id < 0) \
+ return id; \
+ \
+ return sprintf(buf, "%d\n", chips[id].reason[val]); \
+} \
+ \
+static struct kobj_attribute attr_##attr_name = \
+__ATTR(attr_name, 0444, attr_name##_show, NULL)
+
+define_throttle_reason_attr(unthrottle_count, NO_THROTTLE);
+define_throttle_reason_attr(power_cap, POWERCAP);
+define_throttle_reason_attr(cpu_over_temperature, CPU_OVERTEMP);
+define_throttle_reason_attr(power_supply_failure, POWER_SUPPLY_FAILURE);
+define_throttle_reason_attr(over_current, OVERCURRENT);
+define_throttle_reason_attr(occ_reset, OCC_RESET_THROTTLE);
+
+static struct attribute *throttle_reason_attrs[] = {
+ &attr_unthrottle_count.attr,
+ &attr_power_cap.attr,
+ &attr_cpu_over_temperature.attr,
+ &attr_power_supply_failure.attr,
+ &attr_over_current.attr,
+ &attr_occ_reset.attr,
+ NULL
+};
+
+static struct attribute *throttle_stat_attrs[] = {
+ &attr_throttle_frequencies.attr,
+ &attr_throttle_stat.attr,
+ NULL
+};
+
+static const struct attribute_group throttle_reason_group = {
+ .name = "throttle_reasons",
+ .attrs = throttle_reason_attrs,
+};
+
+static const struct attribute_group throttle_stat_group = {
+ .attrs = throttle_stat_attrs,
+};
+
+static const struct attribute_group *throttle_attr_groups[] = {
+ &throttle_stat_group,
+ &throttle_reason_group,
+ NULL
+};
+
/* Helper routines */
/* Access helpers to power mgt SPR */
@@ -327,13 +462,16 @@ static void powernv_cpufreq_throttle_check(void *data)
unsigned int cpu = smp_processor_id();
unsigned int chip_id = core_to_chip_map[cpu_core_index_of_thread(cpu)];
unsigned long pmsr;
- int pmsr_pmax, i;
+ int pmsr_pmax, i, index;
pmsr = get_pmspr(SPRN_PMSR);
- for (i = 0; i < nr_chips; i++)
- if (chips[i].id == chip_id)
- break;
+ i = get_chip_index(chip_id);
+ if (unlikely(i < 0)) {
+ pr_warn_once("%s Matching chip-id not found %d\n", __func__,
+ chip_id);
+ return;
+ }
/* Check for Pmax Capping */
pmsr_pmax = (s8)PMSR_MAX(pmsr);
@@ -341,10 +479,19 @@ static void powernv_cpufreq_throttle_check(void *data)
if (chips[i].throttled)
goto next;
chips[i].throttled = true;
- if (pmsr_pmax < powernv_pstate_info.nominal)
+ 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);
+ chips[i].throttle_nominal++;
+ } else {
+ chips[i].throttle_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].throttle_reason],
pmsr_pmax);
@@ -512,13 +659,19 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,
return 0;
}
- for (i = 0; i < nr_chips; i++)
- if (chips[i].id == omsg.chip)
- break;
+
+ i = get_chip_index(omsg.chip);
+ if (i < 0) {
+ pr_warn_once("%s Matching chip-id not found %d\n",
+ __func__, (int)omsg.chip);
+ return i;
+ }
if (omsg.throttle_status >= 0 &&
- omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS)
+ omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS) {
chips[i].throttle_reason = omsg.throttle_status;
+ chips[i].reason[omsg.throttle_status]++;
+ }
if (!omsg.throttle_status)
chips[i].restore = true;
@@ -583,12 +736,38 @@ static int init_chip_info(void)
goto free_chip_map;
for (i = 0; i < nr_chips; i++) {
+ char name[10];
+
chips[i].id = chip[i];
cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i]));
INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn);
+ chips[i].pstate_stat = kcalloc(powernv_pstate_info.nr_pstates,
+ sizeof(int), GFP_KERNEL);
+ if (!chips[i].pstate_stat)
+ goto free;
+
+ sprintf(name, "chip%d", chips[i].id);
+ chips[i].kobj = kobject_create_and_add(name,
+ cpufreq_global_kobject);
+ if (!chips[i].kobj)
+ goto free;
+
+ ret = sysfs_create_groups(chips[i].kobj, throttle_attr_groups);
+ if (ret) {
+ pr_info("Chip %d failed to create throttle sysfs group\n",
+ chips[i].id);
+ goto free;
+ }
}
return 0;
+free:
+ nr_chips = i;
+ for (i = 0; i <= nr_chips; i++) {
+ kobject_put(chips[i].kobj);
+ kfree(chips[i].pstate_stat);
+ }
+ kfree(chips);
free_chip_map:
kfree(core_to_chip_map);
out:
@@ -623,9 +802,17 @@ module_init(powernv_cpufreq_init);
static void __exit powernv_cpufreq_exit(void)
{
+ int i;
+
unregister_reboot_notifier(&powernv_cpufreq_reboot_nb);
opal_message_notifier_unregister(OPAL_MSG_OCC,
&powernv_cpufreq_opal_nb);
+
+ for (i = 0; i < nr_chips; i++) {
+ kobject_put(chips[i].kobj);
+ kfree(chips[i].pstate_stat);
+ }
+
kfree(chips);
kfree(core_to_chip_map);
cpufreq_unregister_driver(&powernv_cpufreq_driver);
--
1.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v7 6/6] cpufreq: powernv: Add sysfs attributes to show throttle stats
[not found] ` <1453965941-7363-7-git-send-email-shilpa.bhat-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-01-28 8:34 ` Gautham R Shenoy
2016-01-28 11:40 ` Viresh Kumar
1 sibling, 0 replies; 7+ messages in thread
From: Gautham R Shenoy @ 2016-01-28 8:34 UTC (permalink / raw)
To: Shilpasri G Bhat
Cc: linuxppc-dev-mnsaURCQ41sdnm+yROfE0A,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, rjw-LthD3rsA81gm4RdzfppkhA,
viresh.kumar-QSEj5FYQhm4dnm+yROfE0A,
linux-pm-u79uwXL29TY76Z2rM5mHXA, pc-r/Jw6+rmf7HQT0dZR+AlfA,
anton-eUNUBHrolfbYtjvyW6yDsg,
ego-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
shreyas-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
bsingharora-Re5JQEeQqe8AvxtiuMwx3w, mpe-Gsx/Oe8HsFggBc27wqDAHg,
linux-api-u79uwXL29TY76Z2rM5mHXA
Hi Shilpa,
A minor nit.
On Thu, Jan 28, 2016 at 12:55:41PM +0530, Shilpasri G Bhat wrote:
[..snip..]
> +
> +What: /sys/devices/system/cpu/cpufreq/chip*/throttle_reasons/<reason_attributes>
> +Date: Jan 2016
> +Contact: Linux kernel mailing list <linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
> + Linux for PowerPC mailing list <linuxppc-dev-mnsaURCQ41sdnm+yROfE0A@public.gmane.org>
> +Description: CPU Frequency throttle reason stat for the chip
> +
> + This directory contains throttle reason files. Each file gives
> + the total number of times the max frequency is throttled, except
> + for 'unthrottle_count', which gives the total number of times
> + the max frequency is unthrottled after being throttled. Below
> + are the reason attributes.
> +
> + cpu_over_temperature: Throttled due to cpu over temperature
> +
> + occ_reset: Throttled due to reset of OCC
> +
> + over_current: Throttled due to over current
Overcurrent is a single word. No need of the extra space. You could
fix that and add my Reviewed-by.
--
Thanks and Regards
gautham.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v7 6/6] cpufreq: powernv: Add sysfs attributes to show throttle stats
2016-01-28 7:25 ` [PATCH v7 6/6] cpufreq: powernv: Add sysfs attributes to show throttle stats Shilpasri G Bhat
@ 2016-01-28 8:40 ` Viresh Kumar
2016-01-28 9:36 ` Shilpasri G Bhat
[not found] ` <1453965941-7363-7-git-send-email-shilpa.bhat-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
1 sibling, 1 reply; 7+ messages in thread
From: Viresh Kumar @ 2016-01-28 8:40 UTC (permalink / raw)
To: Shilpasri G Bhat
Cc: linuxppc-dev, linux-kernel, rjw, linux-pm, pc, anton, ego,
shreyas, bsingharora, mpe, linux-api
On 28-01-16, 12:55, Shilpasri G Bhat wrote:
> diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
> index b683e8e..dea4620 100644
> --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
> +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
> @@ -271,3 +271,48 @@ Description: Parameters for the CPU cache attributes
> - WriteBack: data is written only to the cache line and
> the modified cache line is written to main
> memory only when it is replaced
> +
> +What: /sys/devices/system/cpu/cpufreq/chip*/throttle_stats
What about the chip directory ? Shouldn't that be documented? And
shouldn't that mention that this is just for powerpc ?
And before that, I don't think that you are doing this properly. I am
sorry that I never came to a point where I could review it, and you
continued with it, version after version.
But, I really have strong objections to the way this is done. And you
are making things more complex then they are.
So, these stats are per-policy, right ?
Then why aren't they added on the policy->kobj instead, just like
cpufreq-stats? And maybe inside cpufreq-stats folder only?
That will solve many complexities you have in place here and will look
sane as well.
Right now, you have stats as two places, cpu/cpufreq/chip/ and
cpu/cpuX/cpufreq/stats/, which doesn't look wise and adds to
confusion.
What do you say?
--
viresh
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v7 6/6] cpufreq: powernv: Add sysfs attributes to show throttle stats
2016-01-28 8:40 ` Viresh Kumar
@ 2016-01-28 9:36 ` Shilpasri G Bhat
[not found] ` <56A9E136.8090900-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
0 siblings, 1 reply; 7+ messages in thread
From: Shilpasri G Bhat @ 2016-01-28 9:36 UTC (permalink / raw)
To: Viresh Kumar
Cc: linuxppc-dev, linux-kernel, rjw, linux-pm, pc, anton, ego,
shreyas, bsingharora, mpe, linux-api
Hi Viresh,
On 01/28/2016 02:10 PM, Viresh Kumar wrote:
> On 28-01-16, 12:55, Shilpasri G Bhat wrote:
>> diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
>> index b683e8e..dea4620 100644
>> --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
>> +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
>> @@ -271,3 +271,48 @@ Description: Parameters for the CPU cache attributes
>> - WriteBack: data is written only to the cache line and
>> the modified cache line is written to main
>> memory only when it is replaced
>> +
>> +What: /sys/devices/system/cpu/cpufreq/chip*/throttle_stats
>
> What about the chip directory ? Shouldn't that be documented? And
> shouldn't that mention that this is just for powerpc ?
>
> And before that, I don't think that you are doing this properly. I am
> sorry that I never came to a point where I could review it, and you
> continued with it, version after version.
>
> But, I really have strong objections to the way this is done. And you
> are making things more complex then they are.
>
> So, these stats are per-policy, right ?
First of all sorry about the version log.
No these stats are not per-policy. They are per-chip. The throttle event is
common for all cores in the chip.
>
> Then why aren't they added on the policy->kobj instead, just like
> cpufreq-stats? And maybe inside cpufreq-stats folder only?
>
> That will solve many complexities you have in place here and will look
> sane as well.
>
> Right now, you have stats as two places, cpu/cpufreq/chip/ and
> cpu/cpuX/cpufreq/stats/, which doesn't look wise and adds to
> confusion.
>
> What do you say?
>
Yes agree that it will be much cleaner with policy->kobj. But using policy->kobj
will result in multiple copies of the throttle-chip stats exported for each
policy in the chip. And moving it to cpu/cpuX/cpufreq/stats/
will add a dependency on CONFIG_CPU_FREQ_STAT
We want throttle attributes to be either in cpu/cpufreq or cpu/cpuX/cpufreq. If
multiple copies is not an issue, then I will move it to cpu/cpuX/cpufreq.
Thanks and Regards,
Shilpa
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v7 6/6] cpufreq: powernv: Add sysfs attributes to show throttle stats
[not found] ` <56A9E136.8090900-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-01-28 9:41 ` Viresh Kumar
2016-01-28 9:54 ` Shilpasri G Bhat
0 siblings, 1 reply; 7+ messages in thread
From: Viresh Kumar @ 2016-01-28 9:41 UTC (permalink / raw)
To: Shilpasri G Bhat
Cc: linuxppc-dev-mnsaURCQ41sdnm+yROfE0A,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, rjw-LthD3rsA81gm4RdzfppkhA,
linux-pm-u79uwXL29TY76Z2rM5mHXA, pc-r/Jw6+rmf7HQT0dZR+AlfA,
anton-eUNUBHrolfbYtjvyW6yDsg,
ego-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
shreyas-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
bsingharora-Re5JQEeQqe8AvxtiuMwx3w, mpe-Gsx/Oe8HsFggBc27wqDAHg,
linux-api-u79uwXL29TY76Z2rM5mHXA
On 28-01-16, 15:06, Shilpasri G Bhat wrote:
> No these stats are not per-policy. They are per-chip. The throttle event is
> common for all cores in the chip.
How do you define a chip? And how is it different then the group of
CPUs represented by the policy ?
--
viresh
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v7 6/6] cpufreq: powernv: Add sysfs attributes to show throttle stats
2016-01-28 9:41 ` Viresh Kumar
@ 2016-01-28 9:54 ` Shilpasri G Bhat
0 siblings, 0 replies; 7+ messages in thread
From: Shilpasri G Bhat @ 2016-01-28 9:54 UTC (permalink / raw)
To: Viresh Kumar
Cc: linuxppc-dev, linux-kernel, rjw, linux-pm, pc, anton, ego,
shreyas, bsingharora, mpe, linux-api
On 01/28/2016 03:11 PM, Viresh Kumar wrote:
> On 28-01-16, 15:06, Shilpasri G Bhat wrote:
>> No these stats are not per-policy. They are per-chip. The throttle event is
>> common for all cores in the chip.
>
> How do you define a chip? And how is it different then the group of
> CPUs represented by the policy ?
>
Chip is a group of policies.
Hmm yes I see your point. We anyways maintain frequency stats which is
per-policy. We might as well have throttle stats exported per-policy which
points to per-chip data.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v7 6/6] cpufreq: powernv: Add sysfs attributes to show throttle stats
[not found] ` <1453965941-7363-7-git-send-email-shilpa.bhat-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-01-28 8:34 ` Gautham R Shenoy
@ 2016-01-28 11:40 ` Viresh Kumar
1 sibling, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2016-01-28 11:40 UTC (permalink / raw)
To: Shilpasri G Bhat
Cc: linuxppc-dev-mnsaURCQ41sdnm+yROfE0A,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, rjw-LthD3rsA81gm4RdzfppkhA,
linux-pm-u79uwXL29TY76Z2rM5mHXA, pc-r/Jw6+rmf7HQT0dZR+AlfA,
anton-eUNUBHrolfbYtjvyW6yDsg,
ego-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
shreyas-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
bsingharora-Re5JQEeQqe8AvxtiuMwx3w, mpe-Gsx/Oe8HsFggBc27wqDAHg,
linux-api-u79uwXL29TY76Z2rM5mHXA
On 28-01-16, 12:55, Shilpasri G Bhat wrote:
> 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
> 'unthrottle_count', 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 unthrottle_count
> 7
Wouldn't it be better to keep a two dimensional table here, something
like: trans_table ?
You can have "reasons" in the vertical dimension and frequencies in
the horizontal one? So, that user can see which frequencies got
throttled and why?
> diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
> index b683e8e..dea4620 100644
> --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
> +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
> @@ -271,3 +271,48 @@ Description: Parameters for the CPU cache attributes
> - WriteBack: data is written only to the cache line and
> the modified cache line is written to main
> memory only when it is replaced
> +
> +What: /sys/devices/system/cpu/cpufreq/chip*/throttle_stats
You need documentation for chip*/ as well..
And how can a user know which policies or CPUs belong to a chip?
> diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
> static struct chip {
> unsigned int id;
> bool throttled;
> @@ -62,6 +72,11 @@ static struct chip {
> u8 throttle_reason;
> cpumask_t mask;
> struct work_struct throttle;
> + int throttle_turbo;
> + int throttle_nominal;
> + int reason[OCC_MAX_REASON];
> + int *pstate_stat;
> + struct kobject *kobj;
> } *chips;
>
> static int nr_chips;
> @@ -196,6 +211,126 @@ static struct freq_attr *powernv_cpu_freq_attr[] = {
> NULL,
> };
>
> +static inline int get_chip_index(unsigned int id)
> +{
> + int i;
> +
> + for (i = 0; i < nr_chips; i++)
> + if (chips[i].id == id)
> + return i;
> +
> + return -EINVAL;
> +}
> +
> +static inline int get_chip_index_from_kobj(struct kobject *kobj)
> +{
> + int ret, id;
> + int len = strlen("chip");
> +
> + ret = kstrtoint(kobj->name + len, 0, &id);
That doesn't look nice. What about keeping the kobject in the 'struct
chip' and using container of here?
You can register the kobject with: kobject_init_and_add().
> + if (ret)
> + return ret;
> +
> + ret = get_chip_index(id);
> + if (ret < 0)
> + pr_warn_once("%s Matching chip-id not found %d\n", __func__,
> + id);
> + return ret;
> +}
> +
> +static ssize_t throttle_freq_show(struct kobject *kobj,
> + struct kobj_attribute *attr, char *buf)
> +{
> + int i, count = 0, id;
> +
> + id = get_chip_index_from_kobj(kobj);
> + if (id < 0)
> + return id;
> +
> + for (i = 0; i < powernv_pstate_info.nr_pstates; i++)
> + count += sprintf(&buf[count], "%d %d\n",
> + powernv_freqs[i].frequency,
> + chips[id].pstate_stat[i]);
> +
> + return count;
> +}
> +
> +static struct kobj_attribute attr_throttle_frequencies =
> +__ATTR(throttle_frequencies, 0444, throttle_freq_show, NULL);
Use DEVICE_ATTR_RO macro ?
> @@ -583,12 +736,38 @@ static int init_chip_info(void)
> goto free_chip_map;
>
> for (i = 0; i < nr_chips; i++) {
> + char name[10];
> +
> chips[i].id = chip[i];
> cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i]));
> INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn);
> + chips[i].pstate_stat = kcalloc(powernv_pstate_info.nr_pstates,
> + sizeof(int), GFP_KERNEL);
> + if (!chips[i].pstate_stat)
> + goto free;
> +
> + sprintf(name, "chip%d", chips[i].id);
Always use snprintf ..
> + chips[i].kobj = kobject_create_and_add(name,
> + cpufreq_global_kobject);
> + if (!chips[i].kobj)
> + goto free;
> +
> + ret = sysfs_create_groups(chips[i].kobj, throttle_attr_groups);
> + if (ret) {
> + pr_info("Chip %d failed to create throttle sysfs group\n",
> + chips[i].id);
> + goto free;
> + }
> }
>
> return 0;
> +free:
> + nr_chips = i;
> + for (i = 0; i <= nr_chips; i++) {
Rather do:
while (--i >= 0) {
kobject_put(chips[i].kobj);
kfree(chips[i].pstate_stat);
}
> + kobject_put(chips[i].kobj);
> + kfree(chips[i].pstate_stat);
You haven't removed the sysfs-group. Also make sure you aren't trying
to free/remove resources you haven't allocated, as the earlier part
can fail after 3 different allocations and you are doing same thing
here for all of them.
> + }
> + kfree(chips);
> free_chip_map:
> kfree(core_to_chip_map);
> out:
> @@ -623,9 +802,17 @@ module_init(powernv_cpufreq_init);
>
> static void __exit powernv_cpufreq_exit(void)
> {
> + int i;
> +
> unregister_reboot_notifier(&powernv_cpufreq_reboot_nb);
> opal_message_notifier_unregister(OPAL_MSG_OCC,
> &powernv_cpufreq_opal_nb);
> +
> + for (i = 0; i < nr_chips; i++) {
> + kobject_put(chips[i].kobj);
remove groups ?
> + kfree(chips[i].pstate_stat);
> + }
> +
> kfree(chips);
> kfree(core_to_chip_map);
> cpufreq_unregister_driver(&powernv_cpufreq_driver);
> --
> 1.9.3
--
viresh
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-01-28 11:40 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1453965941-7363-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com>
2016-01-28 7:25 ` [PATCH v7 6/6] cpufreq: powernv: Add sysfs attributes to show throttle stats Shilpasri G Bhat
2016-01-28 8:40 ` Viresh Kumar
2016-01-28 9:36 ` Shilpasri G Bhat
[not found] ` <56A9E136.8090900-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-01-28 9:41 ` Viresh Kumar
2016-01-28 9:54 ` Shilpasri G Bhat
[not found] ` <1453965941-7363-7-git-send-email-shilpa.bhat-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-01-28 8:34 ` Gautham R Shenoy
2016-01-28 11:40 ` Viresh Kumar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).