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:34:48 +0200 [thread overview]
Message-ID: <1502285688.2759.41.camel@baylibre.com> (raw)
In-Reply-To: <20170809114548.GD20805@n2100.armlinux.org.uk>
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);
If the clock rate could be changed (protected only once) err = 0;
If the clock rate could not be changed: err = -EBUSY;
if you wish to combine clk_rate_protect() and clk_set_rate(), you may use
clk_set_rate_protect() which is added in another patch of this series.
>
> That's rather a lot of code to add to every driver, and given the
> number of times I've seen people get the clk_round_rate() vs
> clk_set_rate() thing wrong, I've zero confidence that folk will get
> this right either.
>
> So, I'd suggest _not_ adding this clk_rate_protect() thing, but
> instead an API that simultaneously sets and protects the rate, so
> driver authors don't have to get involved in details like the above.
>
next prev parent reply other threads:[~2017-08-09 13:34 UTC|newest]
Thread overview: 51+ 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 ` [PATCH v3 01/10] clk: take the prepare lock out of clk_core_set_parent Jerome Brunet
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-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-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-07-12 2:00 ` Stephen Boyd
2017-07-26 17:13 ` Jerome Brunet
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-07-26 0:12 ` Stephen Boyd
2017-07-26 17:18 ` Jerome Brunet
2017-08-04 0:18 ` Stephen Boyd
2017-08-08 22:37 ` Michael Turquette
2017-08-09 2:19 ` Stephen Boyd
2017-08-09 11:45 ` Russell King - ARM Linux
2017-08-09 13:34 ` Jerome Brunet [this message]
2017-08-09 13:40 ` Russell King - ARM Linux
2017-08-09 13:45 ` Jerome Brunet
2017-08-10 16:48 ` Michael Turquette
2017-08-10 16:46 ` Michael Turquette
2017-08-09 13:07 ` Jerome Brunet
2017-08-09 12:18 ` Jerome Brunet
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-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-07-12 2:02 ` Stephen Boyd
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-07-12 2:02 ` Stephen Boyd
2017-06-12 19:44 ` [PATCH v3 09/10] clk: fix incorrect usage of ENOSYS Jerome Brunet
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-20 9:07 ` [PATCH v3 00/10] clk: implement clock rate protection mechanism Linus Walleij
2017-06-20 10:50 ` Jerome Brunet
2017-06-20 11:54 ` Linus Walleij
2017-06-20 12:32 ` Jerome Brunet
2017-06-20 12:47 ` Boris Brezillon
2017-06-22 7:07 ` Quentin Schulz
2017-06-22 10:09 ` Jerome Brunet
2017-06-20 15:29 ` Linus Walleij
2017-06-21 13:15 ` Jerome Brunet
2017-07-12 1:16 ` Stephen Boyd
2017-07-26 17:05 ` Jerome Brunet
2017-07-27 22:44 ` Stephen Boyd
2017-08-08 22:40 ` Michael Turquette
2017-08-09 12:14 ` 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=1502285688.2759.41.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).