linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stephen Boyd <sboyd@kernel.org>
To: Marek Szyprowski <m.szyprowski@samsung.com>,
	Maxime Ripard <maxime@cerno.tech>,
	Mike Turquette <mturquette@baylibre.com>,
	linux-clk@vger.kernel.org
Cc: Jerome Brunet <jbrunet@baylibre.com>,
	Naresh Kamboju <naresh.kamboju@linaro.org>,
	Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
	Alexander Stein <alexander.stein@ew.tq-group.com>,
	Neil Armstrong <narmstrong@baylibre.com>,
	Yassine Oudjana <y.oudjana@protonmail.com>,
	Tony Lindgren <tony@atomide.com>
Subject: Re: [PATCH v9 13/25] clk: Set req_rate on reparenting
Date: Tue, 04 Oct 2022 13:59:50 -0700	[thread overview]
Message-ID: <20221004205952.C7287C433C1@smtp.kernel.org> (raw)
In-Reply-To: <0acc7217-762c-7c0d-45a0-55c384824ce4@samsung.com>

Quoting Marek Szyprowski (2022-10-03 02:59:07)
> On 16.08.2022 13:25, Maxime Ripard wrote:
> > If a non-rate clock started by default with a parent that never
> > registered, core->req_rate will be 0. The expectation is that whenever
> > the parent will be registered, req_rate will be updated with the new
> > value that has just been computed.
> >
> > However, if that clock is a mux, clk_set_parent() can also make that
> > clock no longer orphan. In this case however, we never update req_rate.
> >
> > The natural solution to this would be to update core->rate and
> > core->req_rate in clk_reparent() by calling clk_recalc().
> >
> > However, this doesn't work in all cases. Indeed, clk_recalc() is called
> > by __clk_set_parent_before(), __clk_set_parent() and
> > clk_core_reparent(). Both __clk_set_parent_before() and __clk_set_parent
> > will call clk_recalc() with the enable_lock taken through a call to
> > clk_enable_lock(), the underlying locking primitive being a spinlock.
> >
> > clk_recalc() calls the backing driver .recalc_rate hook, and that
> > implementation might sleep if the underlying device uses a bus with
> > accesses that might sleep, such as i2c.
> >
> > In such a situation, we would end up sleeping while holding a spinlock,
> > and thus in an atomic section.
> >
> > In order to work around this, we can move the core->rate and
> > core->req_rate update to the clk_recalc() calling sites, after the
> > enable_lock has been released if it was taken.
> >
> > The only situation that could still be problematic is the
> > clk_core_reparent() -> clk_reparent() case that doesn't have any
> > locking. clk_core_reparent() is itself called by clk_hw_reparent(),
> > which is then called by 4 drivers:
> >
> >    * clk-stm32mp1.c, stm32/clk-stm32-core.c and tegra/clk-tegra210-emc.c
> >      use it in their set_parent implementation. The set_parent hook is
> >      only called by __clk_set_parent() and clk_change_rate(), both of
> >      them calling it without the enable_lock taken.
> >
> >    * clk/tegra/clk-tegra124-emc.c calls it as part of its set_rate
> >      implementation. set_rate is only called by clk_change_rate(), again
> >      without the enable_lock taken.
> >
> > In both cases we can't end up in a situation where the clk_hw_reparent()
> > caller would hold a spinlock, so it seems like this is a good
> > workaround.
> >
> > Let's also add some unit tests to make sure we cover the original bug.
> >
> > Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com> # imx8mp
> > Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> # exynos4210, meson g12b
> 
> Well, I don't have good news. This patch has my 'tested-by', but this 
> version again doesn't work properly on Meson G12B.
> 
> Linux next-20220929, which contains this patch as commit cb1b1dd96241 
> ("clk: Set req_rate on reparenting") fails to boot on Odroid-N2. I only 
> see a freeze once the modules (I see some messages from meson drm and 
> cpu_freq) are loaded. Could you remind me how to help debugging this 
> issue? I will try to identify which clock causes the issue. Reverting 
> $subject on top of linux-next fixes/hides the problem.
> 
> 
> > Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> > ---
> >   drivers/clk/clk.c      |  22 ++++
> >   drivers/clk/clk_test.c | 239 +++++++++++++++++++++++++++++++++++++++++
> >   2 files changed, 261 insertions(+)
> >
> > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > index 53b28e63deae..91bb1ea0e147 100644
> > --- a/drivers/clk/clk.c
> > +++ b/drivers/clk/clk.c
> > @@ -1765,6 +1765,23 @@ static void clk_core_update_orphan_status(struct clk_core *core, bool is_orphan)
> >               clk_core_update_orphan_status(child, is_orphan);
> >   }
> >   
> > +/*
> > + * Update the orphan rate and req_rate of @core and all its children.
> > + */
> > +static void clk_core_update_orphan_child_rates(struct clk_core *core)
> > +{
> > +     struct clk_core *child;
> > +     unsigned long parent_rate = 0;
> > +
> > +     if (core->parent)
> > +             parent_rate = core->parent->rate;
> > +
> > +     core->rate = core->req_rate = clk_recalc(core, parent_rate);
> > +
> > +     hlist_for_each_entry(child, &core->children, child_node)
> > +             clk_core_update_orphan_child_rates(child);
> > +}
> > +
> >   static void clk_reparent(struct clk_core *core, struct clk_core *new_parent)
> >   {
> >       bool was_orphan = core->orphan;
> > @@ -2506,6 +2527,7 @@ static void clk_core_reparent(struct clk_core *core,
> >                                 struct clk_core *new_parent)
> >   {
> >       clk_reparent(core, new_parent);
> > +     clk_core_update_orphan_child_rates(core);
> >       __clk_recalc_accuracies(core);
> >       __clk_recalc_rates(core, POST_RATE_CHANGE);

I see a problem. __clk_recalc_rates() uses 'core->rate' as "old rate"
but we'll have already destroyed that by calling
clk_core_update_orphan_child_rates() and assigning 'core->rate' to the
recalc_rate. Are clk notifiers being used? If so, it will probably be
confused because the notifier will see the same rate as what was set
instead of the old rate. cpufreq is probably the biggest user of clk
notifiers.

We should add a test for that so when a clk is reparented the old rate
is still what we expected it to be when the notifier is called.

Also, clk_core_update_orphan_child_rates() is poorly named. It doesn't
care at all that the clk is an orphan. It seems like another
__clk_recalc_rates() without the notifier. I have no idea why we need
another recalc rates. Possibly setting the req_rate in
__clk_recalc_rates() is sufficient. Or maybe we should bail out if the
clk doesn't have the orphan bit set.

  reply	other threads:[~2022-10-04 21:00 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-16 11:25 [PATCH v9 00/25] clk: More clock rate fixes and tests Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 01/25] clk: test: Switch to clk_hw_get_clk Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 02/25] clk: Drop the rate range on clk_put() Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 03/25] clk: Skip clamping when rounding if there's no boundaries Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 04/25] clk: Mention that .recalc_rate can return 0 on error Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 05/25] clk: Clarify clk_get_rate() expectations Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 06/25] clk: tests: Add test suites description Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 07/25] clk: tests: Add reference to the orphan mux bug report Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 08/25] clk: tests: Add tests for uncached clock Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 09/25] clk: tests: Add tests for single parent mux Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 10/25] clk: tests: Add tests for mux with multiple parents Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 11/25] clk: tests: Add some tests for orphan " Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 12/25] clk: Take into account uncached clocks in clk_set_rate_range() Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 13/25] clk: Set req_rate on reparenting Maxime Ripard
2022-10-03  9:59   ` Marek Szyprowski
2022-10-04 20:59     ` Stephen Boyd [this message]
2022-10-10  9:56       ` Maxime Ripard
2022-10-10 14:52         ` Maxime Ripard
2022-10-11  1:15           ` Stephen Boyd
2022-08-16 11:25 ` [PATCH v9 14/25] clk: Change clk_core_init_rate_req prototype Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 15/25] clk: Move clk_core_init_rate_req() from clk_core_round_rate_nolock() to its caller Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 16/25] clk: Introduce clk_hw_init_rate_request() Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 17/25] clk: Add our request boundaries in clk_core_init_rate_req Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 18/25] clk: Switch from __clk_determine_rate to clk_core_round_rate_nolock Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 19/25] clk: Introduce clk_core_has_parent() Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 20/25] clk: Constify clk_has_parent() Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 21/25] clk: Stop forwarding clk_rate_requests to the parent Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 22/25] clk: Zero the clk_rate_request structure Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 23/25] clk: Introduce the clk_hw_get_rate_range function Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 24/25] clk: qcom: clk-rcg2: Take clock boundaries into consideration for gfx3d Maxime Ripard
2022-08-16 11:25 ` [PATCH v9 25/25] clk: tests: Add missing test case for ranges Maxime Ripard
2022-08-16 14:07 ` [PATCH v9 00/25] clk: More clock rate fixes and tests Alexander Stein
2022-08-18  6:44 ` Naresh Kamboju
2022-09-02 14:53 ` Maxime Ripard
2022-09-17  8:31   ` Stephen Boyd
2022-09-20 12:35     ` 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=20221004205952.C7287C433C1@smtp.kernel.org \
    --to=sboyd@kernel.org \
    --cc=alexander.stein@ew.tq-group.com \
    --cc=dmitry.baryshkov@linaro.org \
    --cc=jbrunet@baylibre.com \
    --cc=linux-clk@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=maxime@cerno.tech \
    --cc=mturquette@baylibre.com \
    --cc=naresh.kamboju@linaro.org \
    --cc=narmstrong@baylibre.com \
    --cc=tony@atomide.com \
    --cc=y.oudjana@protonmail.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 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).