All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthias Kaehlcke <mka@chromium.org>
To: Leonard Crestez <leonard.crestez@nxp.com>
Cc: "MyungJoo Ham" <myungjoo.ham@samsung.com>,
	"Kyungmin Park" <kyungmin.park@samsung.com>,
	"Chanwoo Choi" <cw00.choi@samsung.com>,
	"Artur Świgoń" <a.swigon@partner.samsung.com>,
	"Saravana Kannan" <saravanak@google.com>,
	"Krzysztof Kozlowski" <krzk@kernel.org>,
	"Alexandre Bailon" <abailon@baylibre.com>,
	"Georgi Djakov" <georgi.djakov@linaro.org>,
	"Abel Vesa" <abel.vesa@nxp.com>, "Jacky Bai" <ping.bai@nxp.com>,
	"Viresh Kumar" <viresh.kumar@linaro.org>,
	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 6/8] PM / devfreq: Add dev_pm_qos support
Date: Thu, 19 Sep 2019 12:12:58 -0700	[thread overview]
Message-ID: <20190919191258.GU133864@google.com> (raw)
In-Reply-To: <feab364d702ba62102f212b7d415d9f768159163.1568764439.git.leonard.crestez@nxp.com>

On Wed, Sep 18, 2019 at 03:18:25AM +0300, Leonard Crestez wrote:
> Register notifiers with the pm_qos framework in order to respond to
> requests for MIN_FREQUENCY and MAX_FREQUENCY.

To make it clear that this change on it's own is a NOP maybe add
something like "No constraints are added for now though.", as in
67d874c3b2c6 ("cpufreq: Register notifiers with the PM QoS framework")

> Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
> ---
>  drivers/devfreq/devfreq.c | 71 +++++++++++++++++++++++++++++++++++++++
>  include/linux/devfreq.h   |  5 +++
>  2 files changed, 76 insertions(+)
> 
> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> index 51a4179e2c69..d8d57318b12c 100644
> --- a/drivers/devfreq/devfreq.c
> +++ b/drivers/devfreq/devfreq.c
> @@ -22,17 +22,20 @@
>  #include <linux/platform_device.h>
>  #include <linux/list.h>
>  #include <linux/printk.h>
>  #include <linux/hrtimer.h>
>  #include <linux/of.h>
> +#include <linux/pm_qos.h>
>  #include "governor.h"
>  
>  #define HZ_PER_KHZ 1000
>  
>  #define CREATE_TRACE_POINTS
>  #include <trace/events/devfreq.h>
>  
> +#define HZ_PER_KHZ	1000
> +
>  static struct class *devfreq_class;
>  
>  /*
>   * devfreq core provides delayed work based load monitoring helper
>   * functions. Governors can use these or can implement their own
> @@ -123,10 +126,16 @@ static void devfreq_get_freq_range(struct devfreq *devfreq,
>  	} else {
>  		*min_freq = freq_table[devfreq->profile->max_state - 1];
>  		*max_freq = freq_table[0];
>  	}
>  
> +	/* constraints from dev_pm_qos: */

nit: QoS constraints?

> +	*min_freq = max(*min_freq, HZ_PER_KHZ * (unsigned long)dev_pm_qos_read_value(
> +				devfreq->dev.parent, DEV_PM_QOS_MIN_FREQUENCY));
> +	*max_freq = min(*max_freq, HZ_PER_KHZ * (unsigned long)dev_pm_qos_read_value(
> +				devfreq->dev.parent, DEV_PM_QOS_MAX_FREQUENCY));
> +
>  	/* constraints from sysfs: */
>  	*min_freq = max(*min_freq, devfreq->min_freq);
>  	*max_freq = min(*max_freq, devfreq->max_freq);
>  
>  	/* constraints from opp interface: */
> @@ -605,10 +614,49 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
>  	mutex_unlock(&devfreq->lock);
>  
>  	return ret;
>  }
>  
> +/**
> + * devfreq_qos_notifier_call() - Common handler for qos freq changes.

nit: QoS

s/freq/constraint/ ?

> + * @devfreq:    the devfreq instance.
> + */
> +static int devfreq_qos_notifier_call(struct devfreq *devfreq)
> +{
> +	int ret;
> +
> +	mutex_lock(&devfreq->lock);
> +	ret = update_devfreq(devfreq);
> +	mutex_unlock(&devfreq->lock);
> +
> +	return ret;
> +}
> +
> +/**
> + * devfreq_qos_min_notifier_call() - Callback for qos min_freq changes.

nit: QoS

> + * @nb:		Should to be devfreq->nb_min

s/to//

> + */
> +static int devfreq_qos_min_notifier_call(struct notifier_block *nb,
> +					 unsigned long val, void *ptr)
> +{
> +	struct devfreq *devfreq = container_of(nb, struct devfreq, nb_min);
> +
> +	return devfreq_qos_notifier_call(devfreq);
> +}
> +
> +/**
> + * devfreq_qos_max_notifier_call() - Callback for qos min_freq changes.

nit: QoS

s/min/max/

> + * @nb:		Should to be devfreq->nb_max

s/to//

> + */
> +static int devfreq_qos_max_notifier_call(struct notifier_block *nb,
> +					 unsigned long val, void *ptr)
> +{
> +	struct devfreq *devfreq = container_of(nb, struct devfreq, nb_max);
> +
> +	return devfreq_qos_notifier_call(devfreq);
> +}
> +
>  /**
>   * devfreq_dev_release() - Callback for struct device to release the device.
>   * @dev:	the devfreq device
>   *
>   * Remove devfreq from the list and release its resources.
> @@ -619,10 +667,15 @@ static void devfreq_dev_release(struct device *dev)
>  
>  	mutex_lock(&devfreq_list_lock);
>  	list_del(&devfreq->node);
>  	mutex_unlock(&devfreq_list_lock);
>  
> +	dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_max,
> +			DEV_PM_QOS_MAX_FREQUENCY);
> +	dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_min,
> +			DEV_PM_QOS_MIN_FREQUENCY);
> +

mega-nit: removing 'max' then 'min' does things in reverse order as
during initialization, which is common practice. But since the order
here doesn't really matter I'd stick to the common min/max order,
might readers save a few milli-seconds wondering why 'max' comes first.

>  	if (devfreq->profile->exit)
>  		devfreq->profile->exit(devfreq->dev.parent);
>  
>  	mutex_destroy(&devfreq->lock);
>  	kfree(devfreq->time_in_state);
> @@ -732,10 +785,27 @@ struct devfreq *devfreq_add_device(struct device *dev,
>  	if (err) {
>  		put_device(&devfreq->dev);
>  		goto err_out;
>  	}
>  
> +	/*
> +	 * Register notifiers for updates to min_freq/max_freq after device is

nit: min/max_freq?

> +	 * initialized (and we can handle notifications) but before the governor
> +	 * is started (which should do an initial enforcement of constraints)
> +	 */
> +	devfreq->nb_min.notifier_call = devfreq_qos_min_notifier_call;
> +	err = dev_pm_qos_add_notifier(devfreq->dev.parent, &devfreq->nb_min,
> +				      DEV_PM_QOS_MIN_FREQUENCY);
> +	if (err)
> +		goto err_devfreq;

IIUC you rely on the notifiers being removed by
devfreq_dev_release(). Does dev_pm_qos_remove_notifier() behave
gracefully if the notifier is not initialized/added or do we need
to use BLOCKING_NOTIFIER_INIT() or similar?

WARNING: multiple messages have this Message-ID (diff)
From: Matthias Kaehlcke <mka@chromium.org>
To: Leonard Crestez <leonard.crestez@nxp.com>
Cc: "Artur Świgoń" <a.swigon@partner.samsung.com>,
	"Abel Vesa" <abel.vesa@nxp.com>,
	"Saravana Kannan" <saravanak@google.com>,
	linux-pm@vger.kernel.org,
	"Viresh Kumar" <viresh.kumar@linaro.org>,
	"Krzysztof Kozlowski" <krzk@kernel.org>,
	"Chanwoo Choi" <cw00.choi@samsung.com>,
	"Kyungmin Park" <kyungmin.park@samsung.com>,
	"MyungJoo Ham" <myungjoo.ham@samsung.com>,
	"Alexandre Bailon" <abailon@baylibre.com>,
	"Georgi Djakov" <georgi.djakov@linaro.org>,
	linux-arm-kernel@lists.infradead.org,
	"Jacky Bai" <ping.bai@nxp.com>
Subject: Re: [PATCH 6/8] PM / devfreq: Add dev_pm_qos support
Date: Thu, 19 Sep 2019 12:12:58 -0700	[thread overview]
Message-ID: <20190919191258.GU133864@google.com> (raw)
In-Reply-To: <feab364d702ba62102f212b7d415d9f768159163.1568764439.git.leonard.crestez@nxp.com>

On Wed, Sep 18, 2019 at 03:18:25AM +0300, Leonard Crestez wrote:
> Register notifiers with the pm_qos framework in order to respond to
> requests for MIN_FREQUENCY and MAX_FREQUENCY.

To make it clear that this change on it's own is a NOP maybe add
something like "No constraints are added for now though.", as in
67d874c3b2c6 ("cpufreq: Register notifiers with the PM QoS framework")

> Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
> ---
>  drivers/devfreq/devfreq.c | 71 +++++++++++++++++++++++++++++++++++++++
>  include/linux/devfreq.h   |  5 +++
>  2 files changed, 76 insertions(+)
> 
> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> index 51a4179e2c69..d8d57318b12c 100644
> --- a/drivers/devfreq/devfreq.c
> +++ b/drivers/devfreq/devfreq.c
> @@ -22,17 +22,20 @@
>  #include <linux/platform_device.h>
>  #include <linux/list.h>
>  #include <linux/printk.h>
>  #include <linux/hrtimer.h>
>  #include <linux/of.h>
> +#include <linux/pm_qos.h>
>  #include "governor.h"
>  
>  #define HZ_PER_KHZ 1000
>  
>  #define CREATE_TRACE_POINTS
>  #include <trace/events/devfreq.h>
>  
> +#define HZ_PER_KHZ	1000
> +
>  static struct class *devfreq_class;
>  
>  /*
>   * devfreq core provides delayed work based load monitoring helper
>   * functions. Governors can use these or can implement their own
> @@ -123,10 +126,16 @@ static void devfreq_get_freq_range(struct devfreq *devfreq,
>  	} else {
>  		*min_freq = freq_table[devfreq->profile->max_state - 1];
>  		*max_freq = freq_table[0];
>  	}
>  
> +	/* constraints from dev_pm_qos: */

nit: QoS constraints?

> +	*min_freq = max(*min_freq, HZ_PER_KHZ * (unsigned long)dev_pm_qos_read_value(
> +				devfreq->dev.parent, DEV_PM_QOS_MIN_FREQUENCY));
> +	*max_freq = min(*max_freq, HZ_PER_KHZ * (unsigned long)dev_pm_qos_read_value(
> +				devfreq->dev.parent, DEV_PM_QOS_MAX_FREQUENCY));
> +
>  	/* constraints from sysfs: */
>  	*min_freq = max(*min_freq, devfreq->min_freq);
>  	*max_freq = min(*max_freq, devfreq->max_freq);
>  
>  	/* constraints from opp interface: */
> @@ -605,10 +614,49 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
>  	mutex_unlock(&devfreq->lock);
>  
>  	return ret;
>  }
>  
> +/**
> + * devfreq_qos_notifier_call() - Common handler for qos freq changes.

nit: QoS

s/freq/constraint/ ?

> + * @devfreq:    the devfreq instance.
> + */
> +static int devfreq_qos_notifier_call(struct devfreq *devfreq)
> +{
> +	int ret;
> +
> +	mutex_lock(&devfreq->lock);
> +	ret = update_devfreq(devfreq);
> +	mutex_unlock(&devfreq->lock);
> +
> +	return ret;
> +}
> +
> +/**
> + * devfreq_qos_min_notifier_call() - Callback for qos min_freq changes.

nit: QoS

> + * @nb:		Should to be devfreq->nb_min

s/to//

> + */
> +static int devfreq_qos_min_notifier_call(struct notifier_block *nb,
> +					 unsigned long val, void *ptr)
> +{
> +	struct devfreq *devfreq = container_of(nb, struct devfreq, nb_min);
> +
> +	return devfreq_qos_notifier_call(devfreq);
> +}
> +
> +/**
> + * devfreq_qos_max_notifier_call() - Callback for qos min_freq changes.

nit: QoS

s/min/max/

> + * @nb:		Should to be devfreq->nb_max

s/to//

> + */
> +static int devfreq_qos_max_notifier_call(struct notifier_block *nb,
> +					 unsigned long val, void *ptr)
> +{
> +	struct devfreq *devfreq = container_of(nb, struct devfreq, nb_max);
> +
> +	return devfreq_qos_notifier_call(devfreq);
> +}
> +
>  /**
>   * devfreq_dev_release() - Callback for struct device to release the device.
>   * @dev:	the devfreq device
>   *
>   * Remove devfreq from the list and release its resources.
> @@ -619,10 +667,15 @@ static void devfreq_dev_release(struct device *dev)
>  
>  	mutex_lock(&devfreq_list_lock);
>  	list_del(&devfreq->node);
>  	mutex_unlock(&devfreq_list_lock);
>  
> +	dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_max,
> +			DEV_PM_QOS_MAX_FREQUENCY);
> +	dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_min,
> +			DEV_PM_QOS_MIN_FREQUENCY);
> +

mega-nit: removing 'max' then 'min' does things in reverse order as
during initialization, which is common practice. But since the order
here doesn't really matter I'd stick to the common min/max order,
might readers save a few milli-seconds wondering why 'max' comes first.

>  	if (devfreq->profile->exit)
>  		devfreq->profile->exit(devfreq->dev.parent);
>  
>  	mutex_destroy(&devfreq->lock);
>  	kfree(devfreq->time_in_state);
> @@ -732,10 +785,27 @@ struct devfreq *devfreq_add_device(struct device *dev,
>  	if (err) {
>  		put_device(&devfreq->dev);
>  		goto err_out;
>  	}
>  
> +	/*
> +	 * Register notifiers for updates to min_freq/max_freq after device is

nit: min/max_freq?

> +	 * initialized (and we can handle notifications) but before the governor
> +	 * is started (which should do an initial enforcement of constraints)
> +	 */
> +	devfreq->nb_min.notifier_call = devfreq_qos_min_notifier_call;
> +	err = dev_pm_qos_add_notifier(devfreq->dev.parent, &devfreq->nb_min,
> +				      DEV_PM_QOS_MIN_FREQUENCY);
> +	if (err)
> +		goto err_devfreq;

IIUC you rely on the notifiers being removed by
devfreq_dev_release(). Does dev_pm_qos_remove_notifier() behave
gracefully if the notifier is not initialized/added or do we need
to use BLOCKING_NOTIFIER_INIT() or similar?

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2019-09-19 19:13 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-18  0:18 [PATCH 0/8] PM / devfreq: Add dev_pm_qos support Leonard Crestez
2019-09-18  0:18 ` Leonard Crestez
2019-09-18  0:18 ` [PATCH 1/8] PM / devfreq: Lock devfreq in trans_stat_show Leonard Crestez
2019-09-18  0:18   ` Leonard Crestez
2019-09-18 21:28   ` Matthias Kaehlcke
2019-09-18 21:28     ` Matthias Kaehlcke
2019-09-19 18:42     ` Leonard Crestez
2019-09-19 18:42       ` Leonard Crestez
2019-09-19 19:25       ` Matthias Kaehlcke
2019-09-19 19:25         ` Matthias Kaehlcke
2019-09-18  0:18 ` [PATCH 2/8] PM / devfreq: Don't fail devfreq_dev_release if not in list Leonard Crestez
2019-09-18  0:18   ` Leonard Crestez
2019-09-18 21:41   ` Matthias Kaehlcke
2019-09-18 21:41     ` Matthias Kaehlcke
2019-09-18  0:18 ` [PATCH 3/8] PM / devfreq: Move more initialization before registration Leonard Crestez
2019-09-18  0:18   ` Leonard Crestez
2019-09-18 23:29   ` Matthias Kaehlcke
2019-09-18 23:29     ` Matthias Kaehlcke
2019-09-19  0:14     ` Matthias Kaehlcke
2019-09-19  0:14       ` Matthias Kaehlcke
2019-09-19 18:52     ` Leonard Crestez
2019-09-19 18:52       ` Leonard Crestez
2019-09-19 19:16       ` Matthias Kaehlcke
2019-09-19 19:16         ` Matthias Kaehlcke
2019-09-18  0:18 ` [PATCH 4/8] PM / devfreq: Don't take lock in devfreq_add_device Leonard Crestez
2019-09-18  0:18   ` Leonard Crestez
2019-09-19  0:20   ` Matthias Kaehlcke
2019-09-19  0:20     ` Matthias Kaehlcke
2019-09-18  0:18 ` [PATCH 5/8] PM / devfreq: Introduce devfreq_get_freq_range Leonard Crestez
2019-09-18  0:18   ` Leonard Crestez
2019-09-19 18:07   ` Matthias Kaehlcke
2019-09-19 18:07     ` Matthias Kaehlcke
2019-09-18  0:18 ` [PATCH 6/8] PM / devfreq: Add dev_pm_qos support Leonard Crestez
2019-09-18  0:18   ` Leonard Crestez
2019-09-19 19:12   ` Matthias Kaehlcke [this message]
2019-09-19 19:12     ` Matthias Kaehlcke
2019-09-18  0:18 ` [PATCH 7/8] PM / devfreq: Use dev_pm_qos for sysfs min/max_freq Leonard Crestez
2019-09-18  0:18   ` Leonard Crestez
2019-09-19 19:59   ` Matthias Kaehlcke
2019-09-19 19:59     ` Matthias Kaehlcke
2019-09-20 13:50     ` Leonard Crestez
2019-09-20 13:50       ` Leonard Crestez
2019-09-18  0:18 ` [PATCH 8/8] PM / devfreq: Move opp notifier registration to core Leonard Crestez
2019-09-18  0:18   ` Leonard Crestez
2019-09-30 21:49   ` Chanwoo Choi
2019-09-30 21:49     ` Chanwoo Choi
2019-10-01 15:14     ` Leonard Crestez
2019-10-01 15:14       ` Leonard Crestez

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=20190919191258.GU133864@google.com \
    --to=mka@chromium.org \
    --cc=a.swigon@partner.samsung.com \
    --cc=abailon@baylibre.com \
    --cc=abel.vesa@nxp.com \
    --cc=cw00.choi@samsung.com \
    --cc=georgi.djakov@linaro.org \
    --cc=krzk@kernel.org \
    --cc=kyungmin.park@samsung.com \
    --cc=leonard.crestez@nxp.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=myungjoo.ham@samsung.com \
    --cc=ping.bai@nxp.com \
    --cc=saravanak@google.com \
    --cc=viresh.kumar@linaro.org \
    /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.