All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rafael@kernel.org>
To: Viresh Kumar <viresh.kumar@linaro.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>,
	Linux PM <linux-pm@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] cpufreq: Make cpufreq_online() call driver->offline() on errors
Date: Tue, 22 Jun 2021 14:18:08 +0200	[thread overview]
Message-ID: <CAJZ5v0jn0W2yG-Ty0NruC-o-V-t9fEjJ=DkzKT1YgZcD3yuJnA@mail.gmail.com> (raw)
In-Reply-To: <20210622062052.jo2by44djlyjpn5w@vireshk-i7>

On Tue, Jun 22, 2021 at 8:20 AM Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
> On 21-06-21, 19:26, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > In the CPU removal path the ->offline() callback provided by the
> > driver is always invoked before ->exit(),
>
> Note that exit() doesn't get called if offline() is present in the CPU
> removal path. We call exit() _only_ when the cpufreq driver gets
> unregistered.

True, but that doesn't contradict what I said.

> > but in the cpufreq_online()
> > error path it is not, so ->exit() is somehow expected to know the
> > context in which it has been called and act accordingly.
>
> I agree, it isn't very clear.
>
> > That is less than straightforward, so make cpufreq_online() invoke
> > the driver's ->offline() callback before ->exit() too.
> >
> > This only potentially affects intel_pstate at this point.
> >
> > Fixes: 91a12e91dc39 ("cpufreq: Allow light-weight tear down and bring up of CPUs")
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/cpufreq/cpufreq.c |    3 +++
> >  1 file changed, 3 insertions(+)
> >
> > Index: linux-pm/drivers/cpufreq/cpufreq.c
> > ===================================================================
> > --- linux-pm.orig/drivers/cpufreq/cpufreq.c
> > +++ linux-pm/drivers/cpufreq/cpufreq.c
> > @@ -1516,6 +1516,9 @@ out_destroy_policy:
> >       up_write(&policy->rwsem);
> >
> >  out_exit_policy:
> > +     if (cpufreq_driver->offline)
> > +             cpufreq_driver->offline(policy);
> > +
> >       if (cpufreq_driver->exit)
> >               cpufreq_driver->exit(policy);
>
> If we want to go down this path, then we better do more and make it
> very explicit that ->offline() follows a previous invocation of
> ->online().
>
> Otherwise, with above we will end up calling ->offline() for two separate
> states, ->online() failed (i.e. two calls to offline() one after the other
> here) and other generic failures after ->init() passed.

Good point.

> So, better make it clear that online/offline are paired like
> init/exit.
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 1d1b563cea4b..0ce48dcb2e8a 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -1347,14 +1347,11 @@ static int cpufreq_online(unsigned int cpu)
>         }
>
>         if (!new_policy && cpufreq_driver->online) {
> -               ret = cpufreq_driver->online(policy);
> -               if (ret) {
> -                       pr_debug("%s: %d: initialization failed\n", __func__,
> -                                __LINE__);
> -                       goto out_exit_policy;
> -               }
> -
> -               /* Recover policy->cpus using related_cpus */
> +               /*
> +                * We did light-weight tear down earlier, don't need to do heavy
> +                * initialization here. Just recover policy->cpus using
> +                * related_cpus.
> +                */
>                 cpumask_copy(policy->cpus, policy->related_cpus);
>         } else {
>                 cpumask_copy(policy->cpus, cpumask_of(cpu));
> @@ -1378,6 +1375,13 @@ static int cpufreq_online(unsigned int cpu)
>                 cpumask_copy(policy->related_cpus, policy->cpus);
>         }
>
> +       ret = cpufreq_driver->online(policy);

But I wouldn't make this change, because that would require reworking
->init() in the driver too.

Let's continue assuming that ->init() will do ->online() if successful
and so ->offline() is needed after a successful ->init() as well as
after a successful ->online().

> +       if (ret) {
> +               pr_debug("%s: %d: %d: ->online() failed\n", __func__, __LINE__,
> +                        ret);
> +               goto out_exit_policy;
> +       }
> +
>         down_write(&policy->rwsem);
>         /*
>          * affected cpus must always be the one, which are online. We aren't
> @@ -1518,6 +1522,9 @@ static int cpufreq_online(unsigned int cpu)
>
>         up_write(&policy->rwsem);
>

So I think that a new label is needed here to avoid running
->offline() after a failing ->online().

Let me update the patch accordingly.

> +       if (cpufreq_driver->offline)
> +               cpufreq_driver->offline(policy);
> +
>  out_exit_policy:
>         if (cpufreq_driver->exit)
>                 cpufreq_driver->exit(policy);

  reply	other threads:[~2021-06-22 12:18 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-21 17:26 [PATCH] cpufreq: Make cpufreq_online() call driver->offline() on errors Rafael J. Wysocki
2021-06-22  6:20 ` Viresh Kumar
2021-06-22 12:18   ` Rafael J. Wysocki [this message]
2021-06-22 19:11 ` [PATCH v2] " Rafael J. Wysocki
2021-06-23  3:10   ` Viresh Kumar

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='CAJZ5v0jn0W2yG-Ty0NruC-o-V-t9fEjJ=DkzKT1YgZcD3yuJnA@mail.gmail.com' \
    --to=rafael@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=rjw@rjwysocki.net \
    --cc=viresh.kumar@linaro.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.