All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Osipenko <dmitry.osipenko@collabora.com>
To: Maxime Ripard <maxime@cerno.tech>,
	Mike Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>
Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>,
	Phil Elwell <phil@raspberrypi.com>,
	Tim Gover <tim.gover@raspberrypi.com>,
	Dom Cobley <dom@raspberrypi.com>,
	dri-devel@lists.freedesktop.org, linux-clk@vger.kernel.org,
	linux-tegra@vger.kernel.org
Subject: Re: [PATCH v7 06/12] clk: Always set the rate on clk_set_range_rate
Date: Tue, 22 Mar 2022 22:05:56 +0300	[thread overview]
Message-ID: <7720158d-10a7-a17b-73a4-a8615c9c6d5c@collabora.com> (raw)
In-Reply-To: <20220225143534.405820-7-maxime@cerno.tech>

On 2/25/22 17:35, Maxime Ripard wrote:
> When we change a clock minimum or maximum using clk_set_rate_range(),
> clk_set_min_rate() or clk_set_max_rate(), the current code will only
> trigger a new rate change if the rate is outside of the new boundaries.
> 
> However, a clock driver might want to always keep the clock rate to
> one of its boundary, for example the minimum to keep the power
> consumption as low as possible.
> 
> Since they don't always get called though, clock providers don't have the
> opportunity to implement this behaviour.
> 
> Let's trigger a clk_set_rate() on the previous requested rate every time
> clk_set_rate_range() is called. That way, providers that care about the
> new boundaries have a chance to adjust the rate, while providers that
> don't care about those new boundaries will return the same rate than
> before, which will be ignored by clk_set_rate() and won't result in a
> new rate change.
> 
> Suggested-by: Stephen Boyd <sboyd@kernel.org>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> ---
>  drivers/clk/clk.c      | 45 ++++++++++++++++----------------
>  drivers/clk/clk_test.c | 58 +++++++++++++++++++-----------------------
>  2 files changed, 49 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index c15ee5070f52..9bc8bf434b94 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -2373,28 +2373,29 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
>  		goto out;
>  	}
>  
> -	rate = clk_core_get_rate_nolock(clk->core);
> -	if (rate < min || rate > max) {
> -		/*
> -		 * FIXME:
> -		 * We are in bit of trouble here, current rate is outside the
> -		 * the requested range. We are going try to request appropriate
> -		 * range boundary but there is a catch. It may fail for the
> -		 * usual reason (clock broken, clock protected, etc) but also
> -		 * because:
> -		 * - round_rate() was not favorable and fell on the wrong
> -		 *   side of the boundary
> -		 * - the determine_rate() callback does not really check for
> -		 *   this corner case when determining the rate
> -		 */
> -
> -		rate = clamp(clk->core->req_rate, min, max);
> -		ret = clk_core_set_rate_nolock(clk->core, rate);
> -		if (ret) {
> -			/* rollback the changes */
> -			clk->min_rate = old_min;
> -			clk->max_rate = old_max;
> -		}
> +	/*
> +	 * Since the boundaries have been changed, let's give the
> +	 * opportunity to the provider to adjust the clock rate based on
> +	 * the new boundaries.
> +	 *
> +	 * We also need to handle the case where the clock is currently
> +	 * outside of the boundaries. Clamping the last requested rate
> +	 * to the current minimum and maximum will also handle this.
> +	 *
> +	 * FIXME:
> +	 * There is a catch. It may fail for the usual reason (clock
> +	 * broken, clock protected, etc) but also because:
> +	 * - round_rate() was not favorable and fell on the wrong
> +	 *   side of the boundary
> +	 * - the determine_rate() callback does not really check for
> +	 *   this corner case when determining the rate
> +	 */
> +	rate = clamp(clk->core->req_rate, min, max);
> +	ret = clk_core_set_rate_nolock(clk->core, rate);
> +	if (ret) {
> +		/* rollback the changes */
> +		clk->min_rate = old_min;
> +		clk->max_rate = old_max;
>  	}
>  
>  out:

Hi,

NVIDIA Tegra30 no longer boots with this change.

You can't assume that rate was requested by clk_set_rate() before
clk_set_rate_range() is called, see what [1] does. T30 memory rate now
drops to min on boot when clk debug range is inited innocuously and CPU
no longer can make any progress because display controller takes out
whole memory bandwidth.

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/memory/tegra/tegra30-emc.c#n1437

If clk_set_rate() wasn't ever invoked and req_rate=0, then you must not
change the clk rate if it's within the new range. Please revert this
patch, thanks.

WARNING: multiple messages have this Message-ID (diff)
From: Dmitry Osipenko <dmitry.osipenko@collabora.com>
To: Maxime Ripard <maxime@cerno.tech>,
	Mike Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>
Cc: Dom Cobley <dom@raspberrypi.com>,
	Tim Gover <tim.gover@raspberrypi.com>,
	Dave Stevenson <dave.stevenson@raspberrypi.com>,
	dri-devel@lists.freedesktop.org,
	Phil Elwell <phil@raspberrypi.com>,
	linux-tegra@vger.kernel.org, linux-clk@vger.kernel.org
Subject: Re: [PATCH v7 06/12] clk: Always set the rate on clk_set_range_rate
Date: Tue, 22 Mar 2022 22:05:56 +0300	[thread overview]
Message-ID: <7720158d-10a7-a17b-73a4-a8615c9c6d5c@collabora.com> (raw)
In-Reply-To: <20220225143534.405820-7-maxime@cerno.tech>

On 2/25/22 17:35, Maxime Ripard wrote:
> When we change a clock minimum or maximum using clk_set_rate_range(),
> clk_set_min_rate() or clk_set_max_rate(), the current code will only
> trigger a new rate change if the rate is outside of the new boundaries.
> 
> However, a clock driver might want to always keep the clock rate to
> one of its boundary, for example the minimum to keep the power
> consumption as low as possible.
> 
> Since they don't always get called though, clock providers don't have the
> opportunity to implement this behaviour.
> 
> Let's trigger a clk_set_rate() on the previous requested rate every time
> clk_set_rate_range() is called. That way, providers that care about the
> new boundaries have a chance to adjust the rate, while providers that
> don't care about those new boundaries will return the same rate than
> before, which will be ignored by clk_set_rate() and won't result in a
> new rate change.
> 
> Suggested-by: Stephen Boyd <sboyd@kernel.org>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> ---
>  drivers/clk/clk.c      | 45 ++++++++++++++++----------------
>  drivers/clk/clk_test.c | 58 +++++++++++++++++++-----------------------
>  2 files changed, 49 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index c15ee5070f52..9bc8bf434b94 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -2373,28 +2373,29 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
>  		goto out;
>  	}
>  
> -	rate = clk_core_get_rate_nolock(clk->core);
> -	if (rate < min || rate > max) {
> -		/*
> -		 * FIXME:
> -		 * We are in bit of trouble here, current rate is outside the
> -		 * the requested range. We are going try to request appropriate
> -		 * range boundary but there is a catch. It may fail for the
> -		 * usual reason (clock broken, clock protected, etc) but also
> -		 * because:
> -		 * - round_rate() was not favorable and fell on the wrong
> -		 *   side of the boundary
> -		 * - the determine_rate() callback does not really check for
> -		 *   this corner case when determining the rate
> -		 */
> -
> -		rate = clamp(clk->core->req_rate, min, max);
> -		ret = clk_core_set_rate_nolock(clk->core, rate);
> -		if (ret) {
> -			/* rollback the changes */
> -			clk->min_rate = old_min;
> -			clk->max_rate = old_max;
> -		}
> +	/*
> +	 * Since the boundaries have been changed, let's give the
> +	 * opportunity to the provider to adjust the clock rate based on
> +	 * the new boundaries.
> +	 *
> +	 * We also need to handle the case where the clock is currently
> +	 * outside of the boundaries. Clamping the last requested rate
> +	 * to the current minimum and maximum will also handle this.
> +	 *
> +	 * FIXME:
> +	 * There is a catch. It may fail for the usual reason (clock
> +	 * broken, clock protected, etc) but also because:
> +	 * - round_rate() was not favorable and fell on the wrong
> +	 *   side of the boundary
> +	 * - the determine_rate() callback does not really check for
> +	 *   this corner case when determining the rate
> +	 */
> +	rate = clamp(clk->core->req_rate, min, max);
> +	ret = clk_core_set_rate_nolock(clk->core, rate);
> +	if (ret) {
> +		/* rollback the changes */
> +		clk->min_rate = old_min;
> +		clk->max_rate = old_max;
>  	}
>  
>  out:

Hi,

NVIDIA Tegra30 no longer boots with this change.

You can't assume that rate was requested by clk_set_rate() before
clk_set_rate_range() is called, see what [1] does. T30 memory rate now
drops to min on boot when clk debug range is inited innocuously and CPU
no longer can make any progress because display controller takes out
whole memory bandwidth.

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/memory/tegra/tegra30-emc.c#n1437

If clk_set_rate() wasn't ever invoked and req_rate=0, then you must not
change the clk rate if it's within the new range. Please revert this
patch, thanks.

  reply	other threads:[~2022-03-22 19:06 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-25 14:35 [PATCH v7 00/12] clk: Improve clock range handling Maxime Ripard
2022-02-25 14:35 ` Maxime Ripard
2022-02-25 14:35 ` [PATCH v7 01/12] clk: Fix clk_hw_get_clk() when dev is NULL Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-02-25 14:35 ` [PATCH v7 02/12] clk: Introduce Kunit Tests for the framework Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-02-25 14:35 ` [PATCH v7 03/12] clk: Enforce that disjoints limits are invalid Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-02-25 14:35 ` [PATCH v7 04/12] clk: Always clamp the rounded rate Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-02-25 14:35 ` [PATCH v7 05/12] clk: Use clamp instead of open-coding our own Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-02-25 14:35 ` [PATCH v7 06/12] clk: Always set the rate on clk_set_range_rate Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-03-22 19:05   ` Dmitry Osipenko [this message]
2022-03-22 19:05     ` Dmitry Osipenko
2022-03-23  8:51     ` Maxime Ripard
2022-03-23  8:51       ` Maxime Ripard
2022-03-24 19:09       ` Stephen Boyd
2022-03-24 19:09         ` Stephen Boyd
2022-03-24 19:25       ` Dmitry Osipenko
2022-03-24 19:25         ` Dmitry Osipenko
2022-02-25 14:35 ` [PATCH v7 07/12] clk: Add clk_drop_range Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-02-25 14:35 ` [PATCH v7 08/12] clk: bcm: rpi: Add variant structure Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-02-25 14:35 ` [PATCH v7 09/12] clk: bcm: rpi: Set a default minimum rate Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-02-25 14:35 ` [PATCH v7 10/12] clk: bcm: rpi: Run some clocks at the minimum rate allowed Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-02-25 14:35 ` [PATCH v7 11/12] drm/vc4: Add logging and comments Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-04-06  8:50   ` Thomas Zimmermann
2022-04-06  8:50     ` Thomas Zimmermann
2022-02-25 14:35 ` [PATCH v7 12/12] drm/vc4: hdmi: Remove clock rate initialization Maxime Ripard
2022-02-25 14:35   ` Maxime Ripard
2022-04-06  8:53   ` Thomas Zimmermann
2022-04-06  8:53     ` Thomas Zimmermann
2022-03-12  3:08 ` [PATCH v7 00/12] clk: Improve clock range handling Stephen Boyd
2022-03-12  3:08   ` Stephen Boyd
2022-03-16  8:37   ` Maxime Ripard
2022-03-16  8:37     ` Maxime Ripard
2022-04-06 10:42 ` Maxime Ripard
2022-04-06 10:42   ` Maxime Ripard

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=7720158d-10a7-a17b-73a4-a8615c9c6d5c@collabora.com \
    --to=dmitry.osipenko@collabora.com \
    --cc=dave.stevenson@raspberrypi.com \
    --cc=dom@raspberrypi.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=maxime@cerno.tech \
    --cc=mturquette@baylibre.com \
    --cc=phil@raspberrypi.com \
    --cc=sboyd@kernel.org \
    --cc=tim.gover@raspberrypi.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.