diff mbox series

PM / devfreq: Add usage_stat file to sysfs

Message ID f70ebc907933717ae5fe2af5bc7f53eed0ef3308.1573508311.git.leonard.crestez@nxp.com (mailing list archive)
State Not Applicable, archived
Headers show
Series PM / devfreq: Add usage_stat file to sysfs | expand

Commit Message

Leonard Crestez Nov. 11, 2019, 9:55 p.m. UTC
This file shows the currently usage of the device as reported by
get_dev_status.

This is the same information used by the ondemand governor to make
decisions and it is not otherwise easily available.

Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
---
 Documentation/ABI/testing/sysfs-class-devfreq |  8 +++++
 drivers/devfreq/devfreq.c                     | 34 +++++++++++++++++++
 2 files changed, 42 insertions(+)

The output might be a little too "free-form" for a sysfs file,
suggestions welcome.
* Splitting it into single-field files would make
reads non-atomic.
* There is currently no debugfs for devfreq

The only current alternative seems to be debug statements in the
driver's implementation of get_dev_status.

Comments

Chanwoo Choi Nov. 12, 2019, 12:46 a.m. UTC | #1
Hi Leonard,

The role of sysfs is not the debugging. We cannot add new sysfs entry
in order to get the load tracking for the debugging. 

For the debugging, use the perf event in linux kernel generally.
And devfreq core already merged the perf event as following:

[1] commit 1be0730f1dcd ("trace: events: add devfreq trace event file")
[2] commit cf451adfa392 ("PM / devfreq: add tracing for scheduling work")

In result, Not Ack of this patch.

Thanks,
Chanwoo Choi

On 11/12/19 6:55 AM, Leonard Crestez wrote:
> This file shows the currently usage of the device as reported by
> get_dev_status.
> 
> This is the same information used by the ondemand governor to make
> decisions and it is not otherwise easily available.
> 
> Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
> ---
>  Documentation/ABI/testing/sysfs-class-devfreq |  8 +++++
>  drivers/devfreq/devfreq.c                     | 34 +++++++++++++++++++
>  2 files changed, 42 insertions(+)
> 
> The output might be a little too "free-form" for a sysfs file,
> suggestions welcome.
> * Splitting it into single-field files would make
> reads non-atomic.
> * There is currently no debugfs for devfreq
> 
> The only current alternative seems to be debug statements in the
> driver's implementation of get_dev_status.
> 
> diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq
> index 01196e19afca..680dab768105 100644
> --- a/Documentation/ABI/testing/sysfs-class-devfreq
> +++ b/Documentation/ABI/testing/sysfs-class-devfreq
> @@ -53,10 +53,18 @@ Description:
>  		the number of transitions between states.
>  		In order to activate this ABI, the devfreq target device
>  		driver should provide the list of available frequencies
>  		with its profile.
>  
> +What:		/sys/class/devfreq/.../usage_stat
> +Date:		November 2019
> +Contact:	Leonard Crestez <leonard.crestez@nxp.com>
> +Description:
> +		This file shows the currently usage of the device if
> +		measurement is enabled. This is the same information used by
> +		ondemand governor to make decisions.
> +
>  What:		/sys/class/devfreq/.../userspace/set_freq
>  Date:		September 2011
>  Contact:	MyungJoo Ham <myungjoo.ham@samsung.com>
>  Description:
>  		The /sys/class/devfreq/.../userspace/set_freq shows and
> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> index 78a5af869a0e..20dce6167946 100644
> --- a/drivers/devfreq/devfreq.c
> +++ b/drivers/devfreq/devfreq.c
> @@ -1559,20 +1559,54 @@ static ssize_t trans_stat_show(struct device *dev,
>  					devfreq->total_trans);
>  	return len;
>  }
>  static DEVICE_ATTR_RO(trans_stat);
>  
> +static ssize_t usage_stat_show(struct device *dev,
> +			       struct device_attribute *attr, char *buf)
> +{
> +	struct devfreq *devfreq = to_devfreq(dev);
> +	struct devfreq_dev_status *stat = &devfreq->last_status;
> +	int ret;
> +	ssize_t len = 0;
> +
> +	if (!devfreq->profile->get_dev_status)
> +		return sprintf(buf, "Not Supported.\n");
> +
> +	if (!devfreq->stop_polling) {
> +		mutex_lock(&devfreq->lock);
> +		ret = devfreq->profile->get_dev_status(dev->parent, stat);
> +		mutex_unlock(&devfreq->lock);
> +		if (ret) {
> +			len += sprintf(buf + len, "Poll error: %d\n", ret);
> +			return len;
> +		}
> +	} else
> +		len += sprintf(buf + len, "Polling stopped\n");
> +
> +	len += sprintf(buf + len, "Busy: %lu\n", stat->busy_time);
> +	len += sprintf(buf + len, "Total: %lu\n", stat->total_time);
> +	len += sprintf(buf + len, "Current Frequency: %lu\n",
> +		       stat->current_frequency);
> +	len += sprintf(buf + len, "Usage: %lu%%\n",
> +		       stat->busy_time * 100 / stat->total_time);
> +
> +	return len;
> +}
> +static DEVICE_ATTR_RO(usage_stat);
> +
>  static struct attribute *devfreq_attrs[] = {
>  	&dev_attr_governor.attr,
>  	&dev_attr_available_governors.attr,
>  	&dev_attr_cur_freq.attr,
>  	&dev_attr_available_frequencies.attr,
>  	&dev_attr_target_freq.attr,
>  	&dev_attr_polling_interval.attr,
>  	&dev_attr_min_freq.attr,
>  	&dev_attr_max_freq.attr,
>  	&dev_attr_trans_stat.attr,
> +	&dev_attr_usage_stat.attr,
>  	NULL,
>  };
>  ATTRIBUTE_GROUPS(devfreq);
>  
>  static int __init devfreq_init(void)
>
Viresh Kumar Nov. 12, 2019, 4:26 a.m. UTC | #2
On 12-11-19, 09:46, Chanwoo Choi wrote:
> Hi Leonard,
> 
> The role of sysfs is not the debugging. We cannot add new sysfs entry
> in order to get the load tracking for the debugging. 
> 
> For the debugging, use the perf event in linux kernel generally.
> And devfreq core already merged the perf event as following:
> 
> [1] commit 1be0730f1dcd ("trace: events: add devfreq trace event file")
> [2] commit cf451adfa392 ("PM / devfreq: add tracing for scheduling work")
> 
> In result, Not Ack of this patch.

Such information if useful can be added to debugfs though.
Chanwoo Choi Nov. 12, 2019, 4:41 a.m. UTC | #3
On 11/12/19 1:26 PM, Viresh Kumar wrote:
> On 12-11-19, 09:46, Chanwoo Choi wrote:
>> Hi Leonard,
>>
>> The role of sysfs is not the debugging. We cannot add new sysfs entry
>> in order to get the load tracking for the debugging. 
>>
>> For the debugging, use the perf event in linux kernel generally.
>> And devfreq core already merged the perf event as following:
>>
>> [1] commit 1be0730f1dcd ("trace: events: add devfreq trace event file")
>> [2] commit cf451adfa392 ("PM / devfreq: add tracing for scheduling work")
>>
>> In result, Not Ack of this patch.
> 
> Such information if useful can be added to debugfs though.

Right. So, I have the plan to make the basic code for devfreq debugfs
because there are some requirements. Thanks.
diff mbox series

Patch

diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq
index 01196e19afca..680dab768105 100644
--- a/Documentation/ABI/testing/sysfs-class-devfreq
+++ b/Documentation/ABI/testing/sysfs-class-devfreq
@@ -53,10 +53,18 @@  Description:
 		the number of transitions between states.
 		In order to activate this ABI, the devfreq target device
 		driver should provide the list of available frequencies
 		with its profile.
 
+What:		/sys/class/devfreq/.../usage_stat
+Date:		November 2019
+Contact:	Leonard Crestez <leonard.crestez@nxp.com>
+Description:
+		This file shows the currently usage of the device if
+		measurement is enabled. This is the same information used by
+		ondemand governor to make decisions.
+
 What:		/sys/class/devfreq/.../userspace/set_freq
 Date:		September 2011
 Contact:	MyungJoo Ham <myungjoo.ham@samsung.com>
 Description:
 		The /sys/class/devfreq/.../userspace/set_freq shows and
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 78a5af869a0e..20dce6167946 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1559,20 +1559,54 @@  static ssize_t trans_stat_show(struct device *dev,
 					devfreq->total_trans);
 	return len;
 }
 static DEVICE_ATTR_RO(trans_stat);
 
+static ssize_t usage_stat_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct devfreq *devfreq = to_devfreq(dev);
+	struct devfreq_dev_status *stat = &devfreq->last_status;
+	int ret;
+	ssize_t len = 0;
+
+	if (!devfreq->profile->get_dev_status)
+		return sprintf(buf, "Not Supported.\n");
+
+	if (!devfreq->stop_polling) {
+		mutex_lock(&devfreq->lock);
+		ret = devfreq->profile->get_dev_status(dev->parent, stat);
+		mutex_unlock(&devfreq->lock);
+		if (ret) {
+			len += sprintf(buf + len, "Poll error: %d\n", ret);
+			return len;
+		}
+	} else
+		len += sprintf(buf + len, "Polling stopped\n");
+
+	len += sprintf(buf + len, "Busy: %lu\n", stat->busy_time);
+	len += sprintf(buf + len, "Total: %lu\n", stat->total_time);
+	len += sprintf(buf + len, "Current Frequency: %lu\n",
+		       stat->current_frequency);
+	len += sprintf(buf + len, "Usage: %lu%%\n",
+		       stat->busy_time * 100 / stat->total_time);
+
+	return len;
+}
+static DEVICE_ATTR_RO(usage_stat);
+
 static struct attribute *devfreq_attrs[] = {
 	&dev_attr_governor.attr,
 	&dev_attr_available_governors.attr,
 	&dev_attr_cur_freq.attr,
 	&dev_attr_available_frequencies.attr,
 	&dev_attr_target_freq.attr,
 	&dev_attr_polling_interval.attr,
 	&dev_attr_min_freq.attr,
 	&dev_attr_max_freq.attr,
 	&dev_attr_trans_stat.attr,
+	&dev_attr_usage_stat.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(devfreq);
 
 static int __init devfreq_init(void)