Message ID | 20230914102317.29302-1-jiazi.li@transsion.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Chanwoo Choi |
Headers | show |
Series | PM / devfreq: Show trans_stat info via debugfs | expand |
Hi Jiazi, kernel test robot noticed the following build warnings: [auto build test WARNING on chanwoo/devfreq-testing] [also build test WARNING on linus/master v6.6-rc1 next-20230914] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Jiazi-Li/PM-devfreq-Show-trans_stat-info-via-debugfs/20230914-182515 base: https://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git devfreq-testing patch link: https://lore.kernel.org/r/20230914102317.29302-1-jiazi.li%40transsion.com patch subject: [PATCH] PM / devfreq: Show trans_stat info via debugfs config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20230914/202309142101.hL5Buk6G-lkp@intel.com/config) compiler: m68k-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230914/202309142101.hL5Buk6G-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202309142101.hL5Buk6G-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/devfreq/devfreq.c:1699: warning: Function parameter or member 'unused' not described in 'devfreq_trans_stat_show' >> drivers/devfreq/devfreq.c:1699: warning: Excess function parameter 'data' description in 'devfreq_trans_stat_show' vim +1699 drivers/devfreq/devfreq.c 1689 1690 /** 1691 * devfreq_trans_stat_show() - show trans stat info through debugfs 1692 * @s: seq_file instance to show trans_stat info of devfreq devices 1693 * @data: not used 1694 * 1695 * Show detailed information for some device which has more than PAGE_SIZE 1696 * bytes of trans stat info. 1697 */ 1698 static int devfreq_trans_stat_show(struct seq_file *s, void *unused) > 1699 { 1700 struct devfreq *df = s->private; 1701 unsigned int max_state; 1702 int i, j; 1703 1704 if (!df->profile) 1705 return -EINVAL; 1706 max_state = df->max_state; 1707 1708 if (max_state == 0) { 1709 seq_puts(s, "Not Supported.\n"); 1710 return 0; 1711 } 1712 1713 mutex_lock(&df->lock); 1714 if (!df->stop_polling && 1715 devfreq_update_status(df, df->previous_freq)) { 1716 mutex_unlock(&df->lock); 1717 return 0; 1718 } 1719 mutex_unlock(&df->lock); 1720 1721 seq_puts(s, " From : To\n"); 1722 seq_puts(s, " :"); 1723 for (i = 0; i < max_state; i++) 1724 seq_printf(s, "%10lu", df->freq_table[i]); 1725 1726 seq_puts(s, " time(ms)\n"); 1727 1728 for (i = 0; i < max_state; i++) { 1729 if (df->freq_table[i] == df->previous_freq) 1730 seq_puts(s, "*"); 1731 else 1732 seq_puts(s, " "); 1733 1734 seq_printf(s, "%10lu:", df->freq_table[i]); 1735 1736 for (j = 0; j < max_state; j++) 1737 seq_printf(s, "%10u", 1738 df->stats.trans_table[(i * max_state) + j]); 1739 1740 seq_printf(s, "%10llu\n", (u64) 1741 jiffies64_to_msecs(df->stats.time_in_state[i])); 1742 } 1743 1744 seq_printf(s, "Total transition : %u\n", df->stats.total_trans); 1745 1746 return 0; 1747 } 1748 DEFINE_SHOW_ATTRIBUTE(devfreq_trans_stat); 1749
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index e36cbb920ec8..08847734ecee 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -940,6 +940,8 @@ struct devfreq *devfreq_add_device(struct device *dev, goto err_init; } create_sysfs_files(devfreq, devfreq->governor); + devfreq->debugfs_dir = + debugfs_create_dir(dev_name(&(devfreq->dev)), devfreq_debugfs); list_add(&devfreq->node, &devfreq_list); @@ -978,6 +980,7 @@ int devfreq_remove_device(struct devfreq *devfreq) devfreq_cooling_unregister(devfreq->cdev); + debugfs_remove_recursive(devfreq->debugfs_dir); if (devfreq->governor) { devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_STOP, NULL); @@ -1682,6 +1685,66 @@ static ssize_t available_frequencies_show(struct device *d, } static DEVICE_ATTR_RO(available_frequencies); +/** + * devfreq_trans_stat_show() - show trans stat info through debugfs + * @s: seq_file instance to show trans_stat info of devfreq devices + * @data: not used + * + * Show detailed information for some device which has more than PAGE_SIZE + * bytes of trans stat info. + */ +static int devfreq_trans_stat_show(struct seq_file *s, void *unused) +{ + struct devfreq *df = s->private; + unsigned int max_state; + int i, j; + + if (!df->profile) + return -EINVAL; + max_state = df->max_state; + + if (max_state == 0) { + seq_puts(s, "Not Supported.\n"); + return 0; + } + + mutex_lock(&df->lock); + if (!df->stop_polling && + devfreq_update_status(df, df->previous_freq)) { + mutex_unlock(&df->lock); + return 0; + } + mutex_unlock(&df->lock); + + seq_puts(s, " From : To\n"); + seq_puts(s, " :"); + for (i = 0; i < max_state; i++) + seq_printf(s, "%10lu", df->freq_table[i]); + + seq_puts(s, " time(ms)\n"); + + for (i = 0; i < max_state; i++) { + if (df->freq_table[i] == df->previous_freq) + seq_puts(s, "*"); + else + seq_puts(s, " "); + + seq_printf(s, "%10lu:", df->freq_table[i]); + + for (j = 0; j < max_state; j++) + seq_printf(s, "%10u", + df->stats.trans_table[(i * max_state) + j]); + + seq_printf(s, "%10llu\n", (u64) + jiffies64_to_msecs(df->stats.time_in_state[i])); + } + + seq_printf(s, "Total transition : %u\n", df->stats.total_trans); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(devfreq_trans_stat); + static ssize_t trans_stat_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1694,8 +1757,22 @@ static ssize_t trans_stat_show(struct device *dev, return -EINVAL; max_state = df->max_state; - if (max_state == 0) + if (max_state == 0) { return sprintf(buf, "Not Supported.\n"); + } else if (max_state > 12) { + /* + * In theory, 13 states will use more than PAGE_SIZE + * bytes, show detail info through debugfs + */ + if (!df->trans_stat) + df->trans_stat = debugfs_create_file("trans_stat", 0444, + df->debugfs_dir, df, + &devfreq_trans_stat_fops); + return sprintf(buf, + "This device's data size exceeds the limit of sysfs.\n" + "Please use debugfs for detailed information:\n" + "/sys/kernel/debug/devfreq/.../trans_stat\n"); + } mutex_lock(&df->lock); if (!df->stop_polling && diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index d312ffbac4dd..7df3f9e51d28 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -209,6 +209,8 @@ struct devfreq { /* information for device frequency transitions */ struct devfreq_stats stats; + struct dentry *debugfs_dir; + struct dentry *trans_stat; struct srcu_notifier_head transition_notifier_list;
For device with over PAGE_SIZE bytes trans_stat info, trans_stat in sysfs just show a prompt information. Create a trans_stat node in debugfs, show detailed information. Signed-off-by: Jiazi Li <jiazi.li@transsion.com> --- drivers/devfreq/devfreq.c | 79 ++++++++++++++++++++++++++++++++++++++- include/linux/devfreq.h | 2 + 2 files changed, 80 insertions(+), 1 deletion(-)