Subject: Re: [PATCH 1/8] PM / devfreq: Lock devfreq in trans_stat_show

From: Matthias Kaehlcke <[email-masked]>
Date: Wed, 18 Sep 2019 14:28:36 -0700

Hi Leonard,

this series doesn't indicate the version, from the change history in
the cover letter I suppose it is v5.

On Wed, Sep 18, 2019 at 03:18:20AM +0300, Leonard Crestez wrote:
> There is no locking in this sysfs show function so stats printing can
> race with a devfreq_update_status called as part of freq switching or
> with initialization.
> 
> Also add an assert in devfreq_update_status to make it clear that lock
> must be held by caller.

This and some other patches look like generic improvements and not
directly related to the series "PM / devfreq: Add dev_pm_qos
support". If there are no dependencies I think it is usually better to
send the improvements separately, it keeps the series more focussed
and might reduce version churn. Just my POV though ;-)

> Signed-off-by: Leonard Crestez <[email-masked]>
> ---
>  drivers/devfreq/devfreq.c | 17 +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> index 2494ee16f502..665575228c4f 100644
> --- a/drivers/devfreq/devfreq.c
> +++ b/drivers/devfreq/devfreq.c
> @@ -159,10 +159,11 @@ int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
>  {
>  	int lev, prev_lev, ret = 0;
>  	unsigned long cur_time;
>  
>  	cur_time = jiffies;
> +	lockdep_assert_held(&devfreq->lock);
>  
>  	/* Immediately exit if previous_freq is not initialized yet. */
>  	if (!devfreq->previous_freq)
>  		goto out;
>  
> @@ -1415,15 +1416,20 @@ static ssize_t trans_stat_show(struct device *dev,
>  	struct devfreq *devfreq = to_devfreq(dev);
>  	ssize_t len;
>  	int i, j;
>  	unsigned int max_state = devfreq->profile->max_state;
>  
> +	mutex_lock(&devfreq->lock);
>  	if (!devfreq->stop_polling &&
> -			devfreq_update_status(devfreq, devfreq->previous_freq))
> -		return 0;
> -	if (max_state == 0)
> -		return sprintf(buf, "Not Supported.\n");
> +			devfreq_update_status(devfreq, devfreq->previous_freq)) {
> +		len = 0;

you could assign 'len' in the declaration instead, but it's just
another option, it'ss fine as is.

> +		goto out;
> +	}
> +	if (max_state == 0) {
> +		len = sprintf(buf, "Not Supported.\n");
> +		goto out;
> +	}

This leaves the general structure of the code as is, which is great,
but since you are already touching this part you can consider to
improve it: 'max_state' is constant after device creation, hence the
check could be done at the beginning, which IMO would be clearer, it
could also save an unnecessary devfreq_update_status() call and it
wouldn't be necessary to hold the lock (one goto less).

>  	len = sprintf(buf, "     From  :   To\n");
>  	len += sprintf(buf + len, "           :");
>  	for (i = 0; i < max_state; i++)
>  		len += sprintf(buf + len, "%10lu",
> @@ -1447,10 +1453,13 @@ static ssize_t trans_stat_show(struct device *dev,
>  			jiffies_to_msecs(devfreq->time_in_state[i]));
>  	}
>  
>  	len += sprintf(buf + len, "Total transition : %u\n",
>  					devfreq->total_trans);
> +
> +out:
> +	mutex_unlock(&devfreq->lock);
>  	return len;
>  }
>  static DEVICE_ATTR_RO(trans_stat);
>  
>  static struct attribute *devfreq_attrs[] = {

My only comments are possible improvements, but the change also looks
good as is, so:

Reviewed-by: Matthias Kaehlcke <[email-masked]>

_______________________________________________
linux-arm-kernel mailing list
[email-masked]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel