From: sboyd@codeaurora.org (Stephen Boyd)
To: linus-amlogic@lists.infradead.org
Subject: [PATCH v3 05/10] clk: add support for clock protection
Date: Tue, 25 Jul 2017 17:12:17 -0700 [thread overview]
Message-ID: <20170726001217.GC2146@codeaurora.org> (raw)
In-Reply-To: <20170612194438.12298-6-jbrunet@baylibre.com>
On 06/12, Jerome Brunet wrote:
> The patch adds clk_protect and clk_unprotect to the CCF API. These
> functions allow a consumer to inform the system that the rate of clock is
> critical to for its operations and it can't tolerate other consumers
s/for//
> changing the rate or introducing glitches while the clock is protected.
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 163cb9832f10..d688b8f59a59 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> +
> +/**
> + * clk_rate_unprotect - unprotect the rate of a clock source
> + * @clk: the clk being unprotected
> + *
> + * clk_unprotect completes a critical section during which the clock
> + * consumer cannot tolerate any change to the clock rate. If no other clock
> + * consumers have protected clocks in the parent chain, then calls to this
> + * function will allow the clocks in the parent chain to change rates
> + * freely.
> + *
> + * Unlike the clk_set_rate_range method, which allows the rate to change
> + * within a given range, protected clocks cannot have their rate changed,
> + * either directly or indirectly due to changes further up the parent chain
> + * of clocks.
> + *
> + * Calls to clk_unprotect must be balanced with calls to clk_protect. Calls
> + * to this function may sleep, and do not return error status.
> + */
> +void clk_rate_unprotect(struct clk *clk)
> +{
> + if (!clk)
> + return;
> +
> + clk_prepare_lock();
> +
> + /*
> + * if there is something wrong with this consumer protect count, stop
> + * here before messing with the provider
> + */
> + if (WARN_ON(clk->protect_count <= 0))
> + goto out;
> +
> + clk_core_rate_unprotect(clk->core);
Can we make this stuff non-recursive? I know that this is
basically a copy paste of prepare/unprepare code and recursion is
nice and elegant, but we really don't need to do it when we could
have a loop that's the same and doesn't blow up our stack frame
usage. I'll send a patch for prepare/enable so you get the idea.
> + clk->protect_count--;
> +out:
> + clk_prepare_unlock();
> +}
> +EXPORT_SYMBOL_GPL(clk_rate_unprotect);
[..]
> +
> @@ -2952,6 +3134,17 @@ void __clk_put(struct clk *clk)
>
> clk_prepare_lock();
>
> + /*
> + * Before calling clk_put, all calls to clk_rate_protect from a given
> + * user must be balanced with calls to clk_rate_unprotect and by that
> + * same user
> + */
> + WARN_ON(clk->protect_count);
> +
> + /* We voiced our concern, let's sanitize the situation */
> + for (; clk->protect_count; clk->protect_count--)
> + clk_core_rate_unprotect(clk->core);
Does this do anything different than:
clk->core->protect_count -= clk->protect_count;
clk->protect_count = 1;
clk_core_rate_unprotect(clk->core);
Just seems better to not do a loop here.
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 91bd464f4c9b..b60c36f2e6b0 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -331,6 +331,30 @@ struct clk *devm_clk_get(struct device *dev, const char *id);
> */
> struct clk *devm_get_clk_from_child(struct device *dev,
> struct device_node *np, const char *con_id);
> +/**
> + * clk_rate_protect - inform the system when the clock rate must be protected.
> + * @clk: clock source
> + *
> + * This function informs the system that the consumer protecting the clock
> + * depends on the rate of the clock source and can't tolerate any glitches
> + * introduced by further clock rate change or re-parenting of the clock source.
> + *
> + * Must not be called from within atomic context.
> + */
> +void clk_rate_protect(struct clk *clk);
Is there any plan to use this clk_rate_protect() API? It seems
inherently racy for a clk consumer to call clk_set_rate() and
then this clk_rate_protect() API after that to lock the rate in.
How about we leave this out of the consumer API until a user
needs it?
I'm tempted to say that we could do this rate locking stuff with
clk_set_rate_range(), but with more thought that doesn't seem
possible because there's a subtle difference. The range API is
willing to accept a range of frequencies, and calling
clk_set_rate_range() with some exact frequency should fail if
that exact frequency can't be met. With this API and the
subsequent clk_set_rate_protect() API we're willing to accept
that the rate we call clk_set_rate_protect() with could be
different than the rate we actually get.
Finally, When does a consumer want the rate of a clk to change
after they call clk_set_rate() on it? I would guess that very few
consumers would be willing to accept that. Which begs the
question, if anyone will keep calling clk_set_rate() after this
API (and the clk_set_rate_protect() API) is added. It almost
seems like we would want it to be opt-out, instead of opt-in, so
that consumers would call clk_set_rate() and expect it to be a
stable clk rate after that, and they would call
clk_set_rate_trample_on_me() or something properly named when
they don't care what the rate is after they call the API.
> +
> +/**
> + * clk_rate_unprotect - release the protection of the clock source.
> + * @clk: clock source
> + *
> + * This function informs the system that the consumer previously protecting the
> + * clock rate can now deal with other consumer altering the clock source rate
other consumers
> + *
> + * The caller must balance the number of rate_protect and rate_unprotect calls.
Please say clk_rate_protect() and clk_rate_unprotect() here.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
WARNING: multiple messages have this Message-ID (diff)
From: Stephen Boyd <sboyd@codeaurora.org>
To: Jerome Brunet <jbrunet@baylibre.com>
Cc: Michael Turquette <mturquette@baylibre.com>,
linux-clk@vger.kernel.org, Kevin Hilman <khilman@baylibre.com>,
linux-amlogic@lists.infradead.org,
Russell King <linux@armlinux.org.uk>,
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: Tue, 25 Jul 2017 17:12:17 -0700 [thread overview]
Message-ID: <20170726001217.GC2146@codeaurora.org> (raw)
In-Reply-To: <20170612194438.12298-6-jbrunet@baylibre.com>
On 06/12, Jerome Brunet wrote:
> The patch adds clk_protect and clk_unprotect to the CCF API. These
> functions allow a consumer to inform the system that the rate of clock is
> critical to for its operations and it can't tolerate other consumers
s/for//
> changing the rate or introducing glitches while the clock is protected.
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 163cb9832f10..d688b8f59a59 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> +
> +/**
> + * clk_rate_unprotect - unprotect the rate of a clock source
> + * @clk: the clk being unprotected
> + *
> + * clk_unprotect completes a critical section during which the clock
> + * consumer cannot tolerate any change to the clock rate. If no other clock
> + * consumers have protected clocks in the parent chain, then calls to this
> + * function will allow the clocks in the parent chain to change rates
> + * freely.
> + *
> + * Unlike the clk_set_rate_range method, which allows the rate to change
> + * within a given range, protected clocks cannot have their rate changed,
> + * either directly or indirectly due to changes further up the parent chain
> + * of clocks.
> + *
> + * Calls to clk_unprotect must be balanced with calls to clk_protect. Calls
> + * to this function may sleep, and do not return error status.
> + */
> +void clk_rate_unprotect(struct clk *clk)
> +{
> + if (!clk)
> + return;
> +
> + clk_prepare_lock();
> +
> + /*
> + * if there is something wrong with this consumer protect count, stop
> + * here before messing with the provider
> + */
> + if (WARN_ON(clk->protect_count <= 0))
> + goto out;
> +
> + clk_core_rate_unprotect(clk->core);
Can we make this stuff non-recursive? I know that this is
basically a copy paste of prepare/unprepare code and recursion is
nice and elegant, but we really don't need to do it when we could
have a loop that's the same and doesn't blow up our stack frame
usage. I'll send a patch for prepare/enable so you get the idea.
> + clk->protect_count--;
> +out:
> + clk_prepare_unlock();
> +}
> +EXPORT_SYMBOL_GPL(clk_rate_unprotect);
[..]
> +
> @@ -2952,6 +3134,17 @@ void __clk_put(struct clk *clk)
>
> clk_prepare_lock();
>
> + /*
> + * Before calling clk_put, all calls to clk_rate_protect from a given
> + * user must be balanced with calls to clk_rate_unprotect and by that
> + * same user
> + */
> + WARN_ON(clk->protect_count);
> +
> + /* We voiced our concern, let's sanitize the situation */
> + for (; clk->protect_count; clk->protect_count--)
> + clk_core_rate_unprotect(clk->core);
Does this do anything different than:
clk->core->protect_count -= clk->protect_count;
clk->protect_count = 1;
clk_core_rate_unprotect(clk->core);
Just seems better to not do a loop here.
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 91bd464f4c9b..b60c36f2e6b0 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -331,6 +331,30 @@ struct clk *devm_clk_get(struct device *dev, const char *id);
> */
> struct clk *devm_get_clk_from_child(struct device *dev,
> struct device_node *np, const char *con_id);
> +/**
> + * clk_rate_protect - inform the system when the clock rate must be protected.
> + * @clk: clock source
> + *
> + * This function informs the system that the consumer protecting the clock
> + * depends on the rate of the clock source and can't tolerate any glitches
> + * introduced by further clock rate change or re-parenting of the clock source.
> + *
> + * Must not be called from within atomic context.
> + */
> +void clk_rate_protect(struct clk *clk);
Is there any plan to use this clk_rate_protect() API? It seems
inherently racy for a clk consumer to call clk_set_rate() and
then this clk_rate_protect() API after that to lock the rate in.
How about we leave this out of the consumer API until a user
needs it?
I'm tempted to say that we could do this rate locking stuff with
clk_set_rate_range(), but with more thought that doesn't seem
possible because there's a subtle difference. The range API is
willing to accept a range of frequencies, and calling
clk_set_rate_range() with some exact frequency should fail if
that exact frequency can't be met. With this API and the
subsequent clk_set_rate_protect() API we're willing to accept
that the rate we call clk_set_rate_protect() with could be
different than the rate we actually get.
Finally, When does a consumer want the rate of a clk to change
after they call clk_set_rate() on it? I would guess that very few
consumers would be willing to accept that. Which begs the
question, if anyone will keep calling clk_set_rate() after this
API (and the clk_set_rate_protect() API) is added. It almost
seems like we would want it to be opt-out, instead of opt-in, so
that consumers would call clk_set_rate() and expect it to be a
stable clk rate after that, and they would call
clk_set_rate_trample_on_me() or something properly named when
they don't care what the rate is after they call the API.
> +
> +/**
> + * clk_rate_unprotect - release the protection of the clock source.
> + * @clk: clock source
> + *
> + * This function informs the system that the consumer previously protecting the
> + * clock rate can now deal with other consumer altering the clock source rate
other consumers
> + *
> + * The caller must balance the number of rate_protect and rate_unprotect calls.
Please say clk_rate_protect() and clk_rate_unprotect() here.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
next prev parent reply other threads:[~2017-07-26 0:12 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 [this message]
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
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=20170726001217.GC2146@codeaurora.org \
--to=sboyd@codeaurora.org \
--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.