Message ID | 1453965941-7363-7-git-send-email-shilpa.bhat@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
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@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 Overcurrent is a single word. No need of the extra space. You could fix that and add my Reviewed-by. -- Thanks and Regards gautham. -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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?
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 -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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 ?
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. -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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
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);
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(-)