All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chanwoo Choi <cw00.choi@samsung.com>
To: Kamil Konieczny <k.konieczny@samsung.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
	Krzysztof Kozlowski <krzk@kernel.org>,
	Kyungmin Park <kyungmin.park@samsung.com>,
	linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
	Marek Szyprowski <m.szyprowski@samsung.com>,
	MyungJoo Ham <myungjoo.ham@samsung.com>
Subject: Re: [PATCH v2 3/3] devfreq: move statistics to separate struct
Date: Thu, 5 Dec 2019 10:46:01 +0900	[thread overview]
Message-ID: <0298e7c0-72ea-ad1d-1a69-68bfaf0d62d1@samsung.com> (raw)
In-Reply-To: <20191204150018.5234-4-k.konieczny@samsung.com>

On 12/5/19 12:00 AM, Kamil Konieczny wrote:
> Count time and transitions between devfreq frequencies in separate struct
> for improved code readability and maintenance.
> 
> Signed-off-by: Kamil Konieczny <k.konieczny@samsung.com>
> ---
> Changes in v2:
>  squash three patches into one, do not modify devfreq_profile and separate stats
>  into devfreq_stats
> 
>  drivers/devfreq/devfreq.c | 68 +++++++++++++++++++++++----------------
>  include/linux/devfreq.h   | 31 ++++++++++++------
>  2 files changed, 62 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> index 901af3b66a76..4d50c8f10bd2 100644
> --- a/drivers/devfreq/devfreq.c
> +++ b/drivers/devfreq/devfreq.c
> @@ -198,6 +198,7 @@ static int set_freq_table(struct devfreq *devfreq)
>   */
>  int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
>  {
> +	struct devfreq_stats *stats = devfreq->stats;
>  	int lev, prev_lev, ret = 0;
>  	unsigned long long cur_time;
>  
> @@ -214,8 +215,8 @@ int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
>  		goto out;
>  	}
>  
> -	devfreq->time_in_state[prev_lev] +=
> -			 cur_time - devfreq->last_stat_updated;
> +	stats->time_in_state[prev_lev] +=
> +			 cur_time - stats->last_stat_updated;
>  
>  	lev = devfreq_get_freq_level(devfreq, freq);
>  	if (lev < 0) {
> @@ -224,13 +225,12 @@ int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
>  	}
>  
>  	if (lev != prev_lev) {
> -		devfreq->trans_table[(prev_lev *
> -				devfreq->profile->max_state) + lev]++;
> -		devfreq->total_trans++;
> +		stats->trans_table[(prev_lev * stats->max_state) + lev]++;
> +		stats->total_trans++;
>  	}
>  
>  out:
> -	devfreq->last_stat_updated = cur_time;
> +	stats->last_stat_updated = cur_time;
>  	return ret;
>  }
>  EXPORT_SYMBOL(devfreq_update_status);
> @@ -525,7 +525,7 @@ void devfreq_monitor_resume(struct devfreq *devfreq)
>  			msecs_to_jiffies(devfreq->profile->polling_ms));
>  
>  out_update:
> -	devfreq->last_stat_updated = get_jiffies_64();
> +	devfreq->stats->last_stat_updated = get_jiffies_64();
>  	devfreq->stop_polling = false;
>  
>  	if (devfreq->profile->get_cur_freq &&
> @@ -735,28 +735,38 @@ struct devfreq *devfreq_add_device(struct device *dev,
>  		goto err_out;
>  	}
>  
> -	devfreq->trans_table = devm_kzalloc(&devfreq->dev,
> +	devfreq->stats = devm_kzalloc(&devfreq->dev, sizeof(*devfreq->stats),
> +				      GFP_KERNEL);

Each devfreq has only one stats structure always. Don't need to define
it with pointer type. It is enough to define as following without pointer type:

	struct devfreq_stats stats;


> +	if (!devfreq->stats) {
> +		mutex_unlock(&devfreq->lock);
> +		err = -ENOMEM;
> +		goto err_devfreq;
> +	}
> +
> +	devfreq->stats->freq_table = devfreq->profile->freq_table;
> +	devfreq->stats->max_state = devfreq->profile->max_state;
> +	devfreq->stats->trans_table = devm_kzalloc(&devfreq->dev,
>  			array3_size(sizeof(unsigned int),
> -				    devfreq->profile->max_state,
> -				    devfreq->profile->max_state),
> +				    devfreq->stats->max_state,
> +				    devfreq->stats->max_state),
>  			GFP_KERNEL);
> -	if (!devfreq->trans_table) {
> +	if (!devfreq->stats->trans_table) {
>  		mutex_unlock(&devfreq->lock);
>  		err = -ENOMEM;
>  		goto err_devfreq;
>  	}
>  
> -	devfreq->time_in_state = devm_kcalloc(&devfreq->dev,
> -			devfreq->profile->max_state,
> -			sizeof(*devfreq->time_in_state),
> +	devfreq->stats->time_in_state = devm_kcalloc(&devfreq->dev,
> +			devfreq->stats->max_state,
> +			sizeof(*devfreq->stats->time_in_state),
>  			GFP_KERNEL);

Actually, this patch will be conflict with patch[1].
[1] https://www.spinics.net/lists/arm-kernel/msg768822.html

First of all, I have to merge patches[1][2] for the devfreq pm-qos
during v5.5-rc period. It requires the linux-pm's maintainer.
[2] https://www.spinics.net/lists/arm-kernel/msg769761.html

After finishing the job[1][2], I'll merge this patch
if finished the review of this patch. Just share the possible merge
conflict to you.


> -	if (!devfreq->time_in_state) {
> +	if (!devfreq->stats->time_in_state) {
>  		mutex_unlock(&devfreq->lock);
>  		err = -ENOMEM;
>  		goto err_devfreq;
>  	}
>  
> -	devfreq->last_stat_updated = get_jiffies_64();
> +	devfreq->stats->last_stat_updated = get_jiffies_64();
>  
>  	srcu_init_notifier_head(&devfreq->transition_notifier_list);
>  
> @@ -1435,9 +1445,10 @@ static ssize_t trans_stat_show(struct device *dev,
>  			       struct device_attribute *attr, char *buf)
>  {
>  	struct devfreq *devfreq = to_devfreq(dev);
> +	struct devfreq_stats *stats = devfreq->stats;
> +	unsigned int max_state = stats->max_state;
>  	ssize_t len;
>  	int i, j;
> -	unsigned int max_state = devfreq->profile->max_state;
>  
>  	if (max_state == 0)
>  		return sprintf(buf, "Not Supported.\n");
> @@ -1454,28 +1465,28 @@ static ssize_t trans_stat_show(struct device *dev,
>  	len += sprintf(buf + len, "           :");
>  	for (i = 0; i < max_state; i++)
>  		len += sprintf(buf + len, "%10lu",
> -				devfreq->profile->freq_table[i]);
> +				stats->freq_table[i]);
>  
>  	len += sprintf(buf + len, "   time(ms)\n");
>  
>  	for (i = 0; i < max_state; i++) {
> -		if (devfreq->profile->freq_table[i]
> +		if (stats->freq_table[i]
>  					== devfreq->previous_freq) {
>  			len += sprintf(buf + len, "*");
>  		} else {
>  			len += sprintf(buf + len, " ");
>  		}
>  		len += sprintf(buf + len, "%10lu:",
> -				devfreq->profile->freq_table[i]);
> +				stats->freq_table[i]);
>  		for (j = 0; j < max_state; j++)
>  			len += sprintf(buf + len, "%10u",
> -				devfreq->trans_table[(i * max_state) + j]);
> +				stats->trans_table[(i * max_state) + j]);
>  		len += sprintf(buf + len, "%10llu\n", (u64)
> -			jiffies64_to_msecs(devfreq->time_in_state[i]));
> +			jiffies64_to_msecs(stats->time_in_state[i]));
>  	}
>  
>  	len += sprintf(buf + len, "Total transition : %u\n",
> -					devfreq->total_trans);
> +					stats->total_trans);
>  	return len;
>  }
>  
> @@ -1484,16 +1495,17 @@ static ssize_t trans_stat_store(struct device *dev,
>  				const char *buf, size_t count)
>  {
>  	struct devfreq *df = to_devfreq(dev);
> -	unsigned int cnt = df->profile->max_state;
> +	struct devfreq_stats *stats = df->stats;
> +	unsigned int cnt = stats->max_state;
>  
>  	if (cnt == 0)
>  		return count;
>  
>  	mutex_lock(&df->lock);
> -	memset(df->time_in_state, 0, cnt * sizeof(u64));
> -	memset(df->trans_table, 0, cnt * cnt * sizeof(int));
> -	df->last_stat_updated = get_jiffies_64();
> -	df->total_trans = 0;
> +	memset(stats->time_in_state, 0, cnt * sizeof(u64));
> +	memset(stats->trans_table, 0, cnt * cnt * sizeof(int));
> +	stats->last_stat_updated = get_jiffies_64();
> +	stats->total_trans = 0;
>  	mutex_unlock(&df->lock);
>  
>  	return count;
> diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
> index b81a86e47fb9..2715719924e7 100644
> --- a/include/linux/devfreq.h
> +++ b/include/linux/devfreq.h
> @@ -106,6 +106,25 @@ struct devfreq_dev_profile {
>  	unsigned int max_state;
>  };
>  
> +/**
> + * struct devfreq_stats - Devfreq's transitions stats counters

Devfreq's transitions stats counters -> Statistics of devfreq device behavior

> + * @freq_table:		List of frequencies in ascending order.
> + * @max_state:		The size of freq_table.
> + * @total_trans:	Number of devfreq transitions.
> + * @trans_table:	Statistics of devfreq transitions.
> + * @time_in_state:	Statistics of devfreq states.
> + * @last_stat_updated:	The last time stats were updated.
> + */
> +struct devfreq_stats {
> +	unsigned long *freq_table;
> +	unsigned int max_state;

Acutally, I'm sorry I has not yet completely agreed to move
'freq_table and 'max_state' from struct devfreq to struct devfreq_stats.
It has not any critical benefit and any problem.
So, don't move 'freq_table' and 'max_state'. 

> +
> +	unsigned int total_trans;
> +	unsigned int *trans_table;
> +	u64 *time_in_state;
> +	unsigned long long last_stat_updated;
> +};
> +
>  /**
>   * struct devfreq - Device devfreq structure
>   * @node:	list node - contains the devices with devfreq that have been
> @@ -131,10 +150,7 @@ struct devfreq_dev_profile {
>   * @suspend_freq:	 frequency of a device set during suspend phase.
>   * @resume_freq:	 frequency of a device set in resume phase.
>   * @suspend_count:	 suspend requests counter for a device.
> - * @total_trans:	Number of devfreq transitions
> - * @trans_table:	Statistics of devfreq transitions
> - * @time_in_state:	Statistics of devfreq states
> - * @last_stat_updated:	The last time stat updated
> + * @stats:	Statistics of devfreq transitions and states times

Statistics of devfreq transitions and states times
-> Statistics of devfreq device behavior

>   * @transition_notifier_list: list head of DEVFREQ_TRANSITION_NOTIFIER notifier
>   *
>   * This structure stores the devfreq information for a give device.
> @@ -171,11 +187,8 @@ struct devfreq {
>  	unsigned long resume_freq;
>  	atomic_t suspend_count;
>  
> -	/* information for device frequency transition */
> -	unsigned int total_trans;
> -	unsigned int *trans_table;
> -	u64 *time_in_state;
> -	unsigned long long last_stat_updated;
> +	/* information for device frequency transitions */
> +	struct devfreq_stats *stats;

Each devfreq has only one stats structure always. Don't need to define
it with pointer type. It is enough to define as following without pointer type:

	struct devfreq_stats stats;

>  
>  	struct srcu_notifier_head transition_notifier_list;
>  };
> 




-- 
Best Regards,
Chanwoo Choi
Samsung Electronics

  parent reply	other threads:[~2019-12-05  1:39 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20191204150032eucas1p1c10713b3308e45e086dd66099057e2b6@eucas1p1.samsung.com>
2019-12-04 15:00 ` [PATCH v2 0/3] devfreq: improve devfreq statistics counting Kamil Konieczny
     [not found]   ` <CGME20191204150033eucas1p1bf11d36a89c89e3eb55c37a1a204e988@eucas1p1.samsung.com>
2019-12-04 15:00     ` [PATCH v2 1/3] devfreq: change time stats to 64-bit Kamil Konieczny
2019-12-05  0:27       ` Chanwoo Choi
2019-12-05  9:58         ` Kamil Konieczny
     [not found]   ` <CGME20191204150033eucas1p164374e7f15cb9a74b7432ca1a822dc10@eucas1p1.samsung.com>
2019-12-04 15:00     ` [PATCH v2 2/3] devfreq: add clearing transitions stats Kamil Konieczny
2019-12-05  0:38       ` Chanwoo Choi
2019-12-05 10:33         ` Kamil Konieczny
     [not found]   ` <CGME20191204150034eucas1p1b6e7f43a6be59ed2e0a4e55ccdefc750@eucas1p1.samsung.com>
2019-12-04 15:00     ` [PATCH v2 3/3] devfreq: move statistics to separate struct Kamil Konieczny
2019-12-05  0:28       ` Matthias Kaehlcke
2019-12-05 14:18         ` Kamil Konieczny
2019-12-05  1:46       ` Chanwoo Choi [this message]
2019-12-05 14:30         ` Kamil Konieczny

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0298e7c0-72ea-ad1d-1a69-68bfaf0d62d1@samsung.com \
    --to=cw00.choi@samsung.com \
    --cc=b.zolnierkie@samsung.com \
    --cc=k.konieczny@samsung.com \
    --cc=krzk@kernel.org \
    --cc=kyungmin.park@samsung.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=myungjoo.ham@samsung.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.