From: mturquette@baylibre.com (Michael Turquette)
To: linus-amlogic@lists.infradead.org
Subject: [RFC 0/7] clk: implement clock locking mechanism
Date: Mon, 15 May 2017 13:09:57 -0700 [thread overview]
Message-ID: <149487899783.2534.12818280336304151266@resonance> (raw)
In-Reply-To: <1494597899.2135.3.camel@baylibre.com>
Hi Jerome,
Quoting Jerome Brunet (2017-05-12 07:04:59)
> On Sat, 2017-04-15 at 21:50 +0200, Michael Turquette wrote:
> > Hi Jerome,
> >
> > Thanks for sending this series. The concept is one we've been talking
> > about for years, and your approach makes sense. Some comments below.
> >
> > Quoting Jerome Brunet (2017-03-21 19:33:23)
> > > This RFC patchset is related to the discussion around CLK_SET_RATE_GATE and
> > > clk_lock which available here [0]
> >
> > If we merge this solution then we may want to convert some of those
> > CLK_SET_RATE_GATE users and
>
> It would be nice, but this would be on a case by case basis and would require
> the help of the platform maintainers. I think there two kind of users of
> CLK_SET_RATE_GATE at this moment:
>
> 1) The clock must be gated - disabled - to change the rate safely:
> clk_protect_rate won't help here, it does not enforce such thing. We should
> provide another fix for this because CLK_SET_RATE_GATE does really enforce this
> constraint along the clock tree either
>
> 2) The one (like me) trying to abuse the enable_count to get some protection:
> This never worked, and these drivers had no protection until now. If they really
> need protection they can start using clk_protect_rate.
>
> What I mean with this two point is: even if the intent is the same, there is
> real functional difference between CLK_SET_RATE_GATE and clk_protect_rate. We
> will have to be careful ...
Agreed. I was only referring to the #2 category above, which I suspect
is a significant portion of them.
>
> > potentially some of the rate-range users
> > that set min/max to the same value over to this new api.
> >
>
> This case is easier, if they use min=max, yes for sure.
>
> > >
> > > The goal of this patchset is to provide a way for consumers to inform the
> > > system that they depend on the rate of the clock source and can't tolerate
> > > other consumers changing the rate or causing glitches.
> > >
> > > Patches 1 to 3 are just rework to ease the integration of the locking
> > > mechanism. They should not introduce any functional differences.
> > >
> > > Patch 4 is the important bit. It introduce 2 new functions to the CCF API:
> > > clk_protect and clk_unprotect (The "lock" word is already used lot in
> > > clk.c. Using clk_lock and clk_unlock would have been very messy. If you
> > > found "protect" to be a poor choice, I'm happy to sed the whole thing in
> > > future version)
> > >
> > > These calls can happen at anytime during the life of the clk. As for
> > > prepare and enable, the calls must be balanced.
> > >
> > > Inside the clock framework, 2 new count values are introduced to keep track
> > > of the protection:
> > > * core "protect_count": this reference count value works in the same way as
> > > ? prepare and enable count, and track whether the clock is protected or
> > > ? not. This is the value that will checked to allow operation which may
> > > ? cause glitches or change the rate of clock source.
> > > * clk consumer "protect_ucount": this allows to track if the consumer is
> > > ? protecting the clock.
> > >
> > > Requiring the consumer to unprotect its clock before changing it would have
> > > been very annoying for the consumer. It would also be unsafe, as it would
> > > still be possible for another consumer to change the rate between the call
> > > to set_rate and protect. This needs to happen in a critical section.??A
> > > solution would be to add "set_rate_protect", but we would need to do the
> > > same for the set_parent and set_phase (and the possible future
> > > functions). It does not scale well.??The solution proposed in this patch is
> > > to use the consumer protect count.
> > >
> > > In function altering the clock, if the consumer is protecting the clock,
> > > the protection is temporarily release under the prepare_lock. This ensure
> > > that:
> > > * the clock is still protect from another consumer because of the
> > > ? prepare_lock
> > > * the rate set on a protected clock cannot change between set_rate and
> > > ? later enable
> > > * only a consumer protecting a clock can do this temporary protection
> > > ? removal (less chance of people messing with the refcount)
> > > * if more than one consumer protect the clock, it remains protected.
> > > ? Because the protection is removed for the calling consumer, it gives
> > > ? it a chance to jump to another provider, if available.
> > >
> > > This protection mechanism assume that "protecting" consumer knows what it
> > > is doing when it comes to setting the rate, and does not expect to be
> > > protected against itself.
> > >
> > > This was tested with the audio use case mentioned in [0]
> > >
> > > One caveat is the following case:
> > > N+1 consumers protect their clocks. These clocks come from N possible
> > > providers. We should able to satisfy at least N consumers before exhausting
> > > the resources.??In the particular case where all the consumers call
> > > "protect" before having a chance to call "set_rate", the last 2 consumers
> > > will remains stuck on the last provider w/o being able to set the rate on
> > > it. This means that in situation where there is 2 consumers on 1
> > > providers, they will compete for the clock, and may end up in situation
> > > where both protect the clock and none can set the rate they need.??This can
> > > be solved if, when the rate fails to be set, the consumer release the
> > > protection. Then the second consumer will be able to satisfy its request.
> >
> > This situation can be handled a bit more gracefully if clk_set_rate_lock
> > both returns an error code if setting the rate failes AND it releases
> > the rate lock in that case. At least that helps for the case of
> > initializing rates during .probe(). Automatically dropping the lock
> > might complicate things in other cases though...
>
> set_rate_lock would solve the problem for?
> > > "the last 2 consumers
> > > will remains stuck on the last provider w/o being able to set the rate"
>
> With set_rate_lock, only the last one won't be satisfied, which is fine I
> suppose.
>
> > ?if setting the rate failes
>
> Setting aside this RFC, when can we consider a that setting the rate failed ?
> CCF always give the best it can, according to a set of constraints (possible
> parents, range of the parents, ...) but does not return an error.
It should return errors if the .set_rate operation fails. That is a
long-standing bug.
I agree that rate selection via .determine_rate is not really a
pass/fail sort of thing.
>
> Clock protect is just one more constraint added to the equation, right ?
>
> set_rate having failed depends on the accuracy you need.
> For exemple You ask for 100Mhz out of :
> * a PLL: you get 98 MHz
> * a very slow clock: you get 10Hz
>
> Which one has failed ?
Again, picking the rate is not the problem. I'm more concerned with PLLs
that will not lock and a timeout is hit in the .set_rate callback from
the PLL clock provider.
Regards,
Mike
>
> Thanks for taking time to review this RFC Mike !
> Cheers
> Jerome
>
> >
> > Best regards,
> > Mike
> >
> > >
> > > Patch 5 is a small change on set_rate_range to restore the old range on
> > > failure. It don't use set_rate_range in any driver so I could not test this
> > > change.
> > >
> > > Patch 6 is just a cosmetic change to clk_summary debugfs entry to make it
> > > less wide after adding protect count in it.
> > >
> > > Patch 7 fix a warning reported by checkpatch.pl. Apparently, ENOSYS is used
> > > incorrectly.
> > >
> > > Bonus:
> > >
> > > With this patchset, we should probably change the use the flags
> > > "CLK_SET_RATE_GATE" and "CLK_SET_PARENT_GATE" We discussed removing
> > > them. Another solution would be to have them automatically gate the clock
> > > before performing the related operation.??What is your view on this ?
> > >
> > > [0]: http://lkml.kernel.org/r/148942423440.82235.17188153691656009029 at resona
> > > nce
> > >
> > > Jerome Brunet (7):
> > > ? clk: take the prepare lock out of clk_core_set_parent
> > > ? clk: add set_phase core function
> > > ? clk: rework calls to round and determine rate callbacks
> > > ? clk: add support for clock protection
> > > ? clk: rollback set_rate_range changes on failure
> > > ? clk: cosmetic changes to clk_summary debugfs entry
> > > ? clk: fix incorrect usage of ENOSYS
> > >
> > > ?drivers/clk/clk.c????????????| 313 ++++++++++++++++++++++++++++++++++----
> > > -----
> > > ?include/linux/clk-provider.h |???1 +
> > > ?include/linux/clk.h??????????|??29 ++++
> > > ?3 files changed, 279 insertions(+), 64 deletions(-)
> > >
> > > --?
> > > 2.9.3
> > >
prev parent reply other threads:[~2017-05-15 20:09 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-21 18:33 Jerome Brunet
2017-03-21 18:33 ` [RFC 1/7] clk: take the prepare lock out of clk_core_set_parent Jerome Brunet
2017-05-11 18:23 ` Michael Turquette
2017-05-12 9:54 ` Jerome Brunet
2017-03-21 18:33 ` [RFC 2/7] clk: add set_phase core function Jerome Brunet
2017-05-11 18:24 ` Michael Turquette
2017-03-21 18:33 ` [RFC 3/7] clk: rework calls to round and determine rate callbacks Jerome Brunet
2017-05-11 18:23 ` Michael Turquette
2017-03-21 18:33 ` [RFC 4/7] clk: add support for clock protection Jerome Brunet
2017-05-11 19:05 ` Michael Turquette
2017-05-12 13:08 ` Jerome Brunet
2017-05-15 20:03 ` Michael Turquette
2017-05-11 19:07 ` Michael Turquette
2017-03-21 18:33 ` [RFC 5/7] clk: rollback set_rate_range changes on failure Jerome Brunet
2017-03-21 18:33 ` [RFC 6/7] clk: cosmetic changes to clk_summary debugfs entry Jerome Brunet
2017-03-21 18:33 ` [RFC 7/7] clk: fix incorrect usage of ENOSYS Jerome Brunet
2017-03-22 0:07 ` [RFC 0/7] clk: implement clock locking mechanism Michael Turquette
2017-03-22 18:13 ` Jerome Brunet
2017-05-11 18:23 ` Michael Turquette
2017-05-12 14:04 ` Jerome Brunet
2017-05-15 20:09 ` Michael Turquette [this message]
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=149487899783.2534.12818280336304151266@resonance \
--to=mturquette@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
all inboxes | Powered by JetHome®