All of lore.kernel.org
 help / color / mirror / Atom feed
From: jbrunet@baylibre.com (Jerome Brunet)
To: linus-amlogic@lists.infradead.org
Subject: [PATCH v3 05/10] clk: add support for clock protection
Date: Wed, 09 Aug 2017 15:45:56 +0200	[thread overview]
Message-ID: <1502286356.2759.43.camel@baylibre.com> (raw)
In-Reply-To: <20170809134036.GE20805@n2100.armlinux.org.uk>

On Wed, 2017-08-09 at 14:40 +0100, Russell King - ARM Linux wrote:
> On Wed, Aug 09, 2017 at 03:34:48PM +0200, Jerome Brunet wrote:
> > On Wed, 2017-08-09 at 12:45 +0100, Russell King - ARM Linux wrote:
> > > On Tue, Aug 08, 2017 at 07:19:06PM -0700, Stephen Boyd wrote:
> > > > I also vaguely remember Paul saying that
> > > > clk_round_rate() could return something and then clk_set_rate()
> > > > after that would fail because what was calculated during the rate
> > > > speculation/rounding phase would be different if some other
> > > > consumer goes and changes some rate high up in the tree.
> > > 
> > > That's probably because people tend to get this stuff wrong.??It is
> > > _not_ supposed to be:
> > > 
> > > 	rounded_rate = clk_round_rate(clk, requested_rate);
> > > 
> > > 	clk_set_rate(clk, rounded_rate);
> > > 
> > > but:
> > > 
> > > 	rounded_rate = clk_round_rate(clk, requested_rate);
> > > 
> > > 	clk_set_rate(clk, requested_rate);
> > > 
> > > The former is wrong for two reasons:
> > > 
> > > 1. it's completely wasteful of CPU resources to do all the calculations
> > > ???that need to be done within clk_set_rate().
> > > 
> > > 2. it's racy - there is no guarantee that you'll end up with
> > > "rounded_rate"
> > > 
> > > The API definition of clk_round_rate() explicitly mentions that it is
> > > equivalent to clk_set_rate() followed by clk_get_rate() with the
> > > exception that it doesn't affect the hardware.
> > > 
> > > I'm not sure that the clock rate protection API is really the right
> > > solution - if we're trying to stop others from changing the clock rate,
> > > that implies we have multiple different threads potentially changing
> > > the rate at any time.??If a driver does this:
> > > 
> > > 	clk_set_rate(clk, foo);
> > > 	clk_rate_protect(clk);
> > > 
> > > what prevents another thread from changing the clock rate between these
> > > two calls???The only way to do this safely would be something like:
> > > 
> > > 	r = clk_round_rate(clk, foo);
> > > 	while (1) {
> > > 		err = clk_set_rate(clk, foo);
> > > 		clk_rate_protect(clk);
> > > 		if (err < 0)
> > > 			break;
> > > 
> > > 		if (r == clk_get_rate(clk)) /* success */
> > > 			break;
> > > 
> > > 		clk_rate_unprotect(clk);
> > > 	}
> > > 
> > > 	if (err)
> > > 		failed;
> > 
> > Russell,
> > I think you have missed one subtle thing, when trying any clock altering
> > operation, if the consumer is protecting the clock, it will temporarily
> > release?
> > the protection once, under the prepare_lock (to guarantee safe operation).
> > This
> > is explained in the cover letter:
> > 
> > """
> > With this series there is 3 use-case:
> > ?- the provider is not protected: nothing changes
> > ?- the provider is protected by only 1 consumer (and only once), then only
> > ???this consumer will be able to alter the rate of the clock, as it is the
> > ???only one depending on it.
> > ?- If the provider is protected more than once, or by the provider itself,
> > ???the rate is basically locked and protected against reparenting.
> > """
> > 
> > So what you should do if you have to protect the clock is:
> > 
> > clk_rate_protect(clk);
> > err = clk_set_rate(clk, foo);
> > 
> > [...]
> > clk_rate_unprotect(clk);
> 
> So here you drop the protection, which means anyone can alter the clock
> again.
> 

That's just an example. The rate is set after clk_set_rate() if no other
consumer depends on the clock.

I just added clk_rate_unprotect() here to illustrate that the calls should be
balanced, as documented.

> Either that or "clk_rate_unprotect" is inappropriately named and doesn't
> do what it says it does.
> 

WARNING: multiple messages have this Message-ID (diff)
From: Jerome Brunet <jbrunet@baylibre.com>
To: Russell King - ARM Linux <linux@armlinux.org.uk>
Cc: Stephen Boyd <sboyd@codeaurora.org>,
	Michael Turquette <mturquette@baylibre.com>,
	linux-clk@vger.kernel.org, Kevin Hilman <khilman@baylibre.com>,
	linux-amlogic@lists.infradead.org,
	Linus Walleij <linus.walleij@linaro.org>,
	Boris Brezillon <boris.brezillon@free-electrons.com>
Subject: Re: [PATCH v3 05/10] clk: add support for clock protection
Date: Wed, 09 Aug 2017 15:45:56 +0200	[thread overview]
Message-ID: <1502286356.2759.43.camel@baylibre.com> (raw)
In-Reply-To: <20170809134036.GE20805@n2100.armlinux.org.uk>

On Wed, 2017-08-09 at 14:40 +0100, Russell King - ARM Linux wrote:
> On Wed, Aug 09, 2017 at 03:34:48PM +0200, Jerome Brunet wrote:
> > On Wed, 2017-08-09 at 12:45 +0100, Russell King - ARM Linux wrote:
> > > On Tue, Aug 08, 2017 at 07:19:06PM -0700, Stephen Boyd wrote:
> > > > I also vaguely remember Paul saying that
> > > > clk_round_rate() could return something and then clk_set_rate()
> > > > after that would fail because what was calculated during the rate
> > > > speculation/rounding phase would be different if some other
> > > > consumer goes and changes some rate high up in the tree.
> > > 
> > > That's probably because people tend to get this stuff wrong.  It is
> > > _not_ supposed to be:
> > > 
> > > 	rounded_rate = clk_round_rate(clk, requested_rate);
> > > 
> > > 	clk_set_rate(clk, rounded_rate);
> > > 
> > > but:
> > > 
> > > 	rounded_rate = clk_round_rate(clk, requested_rate);
> > > 
> > > 	clk_set_rate(clk, requested_rate);
> > > 
> > > The former is wrong for two reasons:
> > > 
> > > 1. it's completely wasteful of CPU resources to do all the calculations
> > >    that need to be done within clk_set_rate().
> > > 
> > > 2. it's racy - there is no guarantee that you'll end up with
> > > "rounded_rate"
> > > 
> > > The API definition of clk_round_rate() explicitly mentions that it is
> > > equivalent to clk_set_rate() followed by clk_get_rate() with the
> > > exception that it doesn't affect the hardware.
> > > 
> > > I'm not sure that the clock rate protection API is really the right
> > > solution - if we're trying to stop others from changing the clock rate,
> > > that implies we have multiple different threads potentially changing
> > > the rate at any time.  If a driver does this:
> > > 
> > > 	clk_set_rate(clk, foo);
> > > 	clk_rate_protect(clk);
> > > 
> > > what prevents another thread from changing the clock rate between these
> > > two calls?  The only way to do this safely would be something like:
> > > 
> > > 	r = clk_round_rate(clk, foo);
> > > 	while (1) {
> > > 		err = clk_set_rate(clk, foo);
> > > 		clk_rate_protect(clk);
> > > 		if (err < 0)
> > > 			break;
> > > 
> > > 		if (r == clk_get_rate(clk)) /* success */
> > > 			break;
> > > 
> > > 		clk_rate_unprotect(clk);
> > > 	}
> > > 
> > > 	if (err)
> > > 		failed;
> > 
> > Russell,
> > I think you have missed one subtle thing, when trying any clock altering
> > operation, if the consumer is protecting the clock, it will temporarily
> > release 
> > the protection once, under the prepare_lock (to guarantee safe operation).
> > This
> > is explained in the cover letter:
> > 
> > """
> > With this series there is 3 use-case:
> >  - the provider is not protected: nothing changes
> >  - the provider is protected by only 1 consumer (and only once), then only
> >    this consumer will be able to alter the rate of the clock, as it is the
> >    only one depending on it.
> >  - If the provider is protected more than once, or by the provider itself,
> >    the rate is basically locked and protected against reparenting.
> > """
> > 
> > So what you should do if you have to protect the clock is:
> > 
> > clk_rate_protect(clk);
> > err = clk_set_rate(clk, foo);
> > 
> > [...]
> > clk_rate_unprotect(clk);
> 
> So here you drop the protection, which means anyone can alter the clock
> again.
> 

That's just an example. The rate is set after clk_set_rate() if no other
consumer depends on the clock.

I just added clk_rate_unprotect() here to illustrate that the calls should be
balanced, as documented.

> Either that or "clk_rate_unprotect" is inappropriately named and doesn't
> do what it says it does.
> 

  reply	other threads:[~2017-08-09 13:45 UTC|newest]

Thread overview: 102+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-12 19:44 [PATCH v3 00/10] clk: implement clock rate protection mechanism Jerome Brunet
2017-06-12 19:44 ` Jerome Brunet
2017-06-12 19:44 ` [PATCH v3 01/10] clk: take the prepare lock out of clk_core_set_parent Jerome Brunet
2017-06-12 19:44   ` Jerome Brunet
2017-07-12  1:21   ` Stephen Boyd
2017-07-12  1:21     ` Stephen Boyd
2017-06-12 19:44 ` [PATCH v3 02/10] clk: add clk_core_set_phase_nolock function Jerome Brunet
2017-06-12 19:44   ` Jerome Brunet
2017-07-12  1:22   ` Stephen Boyd
2017-07-12  1:22     ` Stephen Boyd
2017-06-12 19:44 ` [PATCH v3 03/10] clk: rework calls to round and determine rate callbacks Jerome Brunet
2017-06-12 19:44   ` Jerome Brunet
2017-07-12  1:49   ` Stephen Boyd
2017-07-12  1:49     ` Stephen Boyd
2017-06-12 19:44 ` [PATCH v3 04/10] clk: use round rate to bail out early in set_rate Jerome Brunet
2017-06-12 19:44   ` Jerome Brunet
2017-07-12  2:00   ` Stephen Boyd
2017-07-12  2:00     ` Stephen Boyd
2017-07-26 17:13     ` Jerome Brunet
2017-07-26 17:13       ` Jerome Brunet
2017-08-04  0:32       ` Stephen Boyd
2017-08-04  0:32         ` Stephen Boyd
2017-06-12 19:44 ` [PATCH v3 05/10] clk: add support for clock protection Jerome Brunet
2017-06-12 19:44   ` Jerome Brunet
2017-07-26  0:12   ` Stephen Boyd
2017-07-26  0:12     ` Stephen Boyd
2017-07-26 17:18     ` Jerome Brunet
2017-07-26 17:18       ` Jerome Brunet
2017-08-04  0:18       ` Stephen Boyd
2017-08-04  0:18         ` Stephen Boyd
2017-08-08 22:37         ` Michael Turquette
2017-08-08 22:37           ` Michael Turquette
2017-08-09  2:19           ` Stephen Boyd
2017-08-09  2:19             ` Stephen Boyd
2017-08-09 11:45             ` Russell King - ARM Linux
2017-08-09 11:45               ` Russell King - ARM Linux
2017-08-09 13:34               ` Jerome Brunet
2017-08-09 13:34                 ` Jerome Brunet
2017-08-09 13:40                 ` Russell King - ARM Linux
2017-08-09 13:40                   ` Russell King - ARM Linux
2017-08-09 13:45                   ` Jerome Brunet [this message]
2017-08-09 13:45                     ` Jerome Brunet
2017-08-10 16:48                   ` Michael Turquette
2017-08-10 16:48                     ` Michael Turquette
2017-08-10 16:46               ` Michael Turquette
2017-08-10 16:46                 ` Michael Turquette
2017-08-09 13:07             ` Jerome Brunet
2017-08-09 13:07               ` Jerome Brunet
2017-08-09 12:18           ` Jerome Brunet
2017-08-09 12:18             ` Jerome Brunet
2017-08-10 16:54             ` Michael Turquette
2017-08-10 16:54               ` Michael Turquette
2017-06-12 19:44 ` [PATCH v3 06/10] clk: add clk_set_rate_protect Jerome Brunet
2017-06-12 19:44   ` Jerome Brunet
2017-07-26  0:59   ` Stephen Boyd
2017-07-26  0:59     ` Stephen Boyd
2017-06-12 19:44 ` [PATCH v3 07/10] clk: rollback set_rate_range changes on failure Jerome Brunet
2017-06-12 19:44   ` Jerome Brunet
2017-07-12  2:02   ` Stephen Boyd
2017-07-12  2:02     ` Stephen Boyd
2017-07-26 17:22     ` Jerome Brunet
2017-07-26 17:22       ` Jerome Brunet
2017-06-12 19:44 ` [PATCH v3 08/10] clk: cosmetic changes to clk_summary debugfs entry Jerome Brunet
2017-06-12 19:44   ` Jerome Brunet
2017-07-12  2:02   ` Stephen Boyd
2017-07-12  2:02     ` Stephen Boyd
2017-06-12 19:44 ` [PATCH v3 09/10] clk: fix incorrect usage of ENOSYS Jerome Brunet
2017-06-12 19:44   ` Jerome Brunet
2017-07-12  2:03   ` Stephen Boyd
2017-07-12  2:03     ` Stephen Boyd
2017-06-12 19:44 ` [PATCH v3 10/10] clk: fix CLK_SET_RATE_GATE with clock rate protection Jerome Brunet
2017-06-12 19:44   ` Jerome Brunet
2017-06-20  9:07 ` [PATCH v3 00/10] clk: implement clock rate protection mechanism Linus Walleij
2017-06-20  9:07   ` Linus Walleij
2017-06-20 10:50   ` Jerome Brunet
2017-06-20 10:50     ` Jerome Brunet
2017-06-20 11:54     ` Linus Walleij
2017-06-20 11:54       ` Linus Walleij
2017-06-20 12:32       ` Jerome Brunet
2017-06-20 12:32         ` Jerome Brunet
2017-06-20 12:47         ` Boris Brezillon
2017-06-20 12:47           ` Boris Brezillon
2017-06-22  7:07           ` Quentin Schulz
2017-06-22  7:07             ` Quentin Schulz
2017-06-22 10:09             ` Jerome Brunet
2017-06-22 10:09               ` Jerome Brunet
2017-06-20 15:29         ` Linus Walleij
2017-06-20 15:29           ` Linus Walleij
2017-06-21 13:15         ` Jerome Brunet
2017-06-21 13:15           ` Jerome Brunet
2017-07-12  1:16           ` Stephen Boyd
2017-07-12  1:16             ` Stephen Boyd
2017-07-26 17:05             ` Jerome Brunet
2017-07-26 17:05               ` Jerome Brunet
2017-07-27 22:44               ` Stephen Boyd
2017-07-27 22:44                 ` Stephen Boyd
2017-08-08 22:40                 ` Michael Turquette
2017-08-08 22:40                   ` Michael Turquette
2017-08-09 12:14                   ` Jerome Brunet
2017-08-09 12:14                     ` Jerome Brunet
2017-07-11 21:04 ` Jerome Brunet
2017-07-11 21:04   ` Jerome Brunet

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=1502286356.2759.43.camel@baylibre.com \
    --to=jbrunet@baylibre.com \
    --cc=linus-amlogic@lists.infradead.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.