linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] PM: sleep: call devfreq_suspend/resume and cpufreq_suspend/resume in pairs.
@ 2020-04-22  5:15 Chunyan Zhang
  2020-04-22  9:05 ` Rafael J. Wysocki
  0 siblings, 1 reply; 5+ messages in thread
From: Chunyan Zhang @ 2020-04-22  5:15 UTC (permalink / raw)
  To: Rafael J . Wysocki, Greg Kroah-Hartman, Len Brown, Pavel Machek
  Cc: linux-pm, linux-kernel, Orson Zhai, Chunyan Zhang, Vincent Wang,
	Samer Xie, Chunyan Zhang

From: Vincent Wang <vincent.wang@unisoc.com>

If dpm_prepare() fails in dpm_suspend_start(), dpm_suspend() can't be
called. And then, devfreq_suspend() and cpufreq_suspend() will not be
called in the suspend flow.

But in the resiume flow, devfreq_resume() and cpufreq_resume() will
be called.

This patch will ensure that devfreq_suspend/devfreq_resume and
cpufreq_suspend/cpufreq_resume are called in pairs.

Signed-off-by: Vincent Wang <vincent.wang@unisoc.com>
Signed-off-by: Samer Xie <samer.xie@unisoc.com>
Signed-off-by: Chunyan Zhang <zhang.lyra@gmail.com>
---
 drivers/base/power/main.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index fdd508a78ffd..eb3d987d43e0 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1866,9 +1866,6 @@ int dpm_suspend(pm_message_t state)
 	trace_suspend_resume(TPS("dpm_suspend"), state.event, true);
 	might_sleep();
 
-	devfreq_suspend();
-	cpufreq_suspend();
-
 	mutex_lock(&dpm_list_mtx);
 	pm_transition = state;
 	async_error = 0;
@@ -1988,6 +1985,9 @@ int dpm_prepare(pm_message_t state)
 	trace_suspend_resume(TPS("dpm_prepare"), state.event, true);
 	might_sleep();
 
+	devfreq_suspend();
+	cpufreq_suspend();
+
 	/*
 	 * Give a chance for the known devices to complete their probes, before
 	 * disable probing of devices. This sync point is important at least
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] PM: sleep: call devfreq_suspend/resume and cpufreq_suspend/resume in pairs.
  2020-04-22  5:15 [PATCH] PM: sleep: call devfreq_suspend/resume and cpufreq_suspend/resume in pairs Chunyan Zhang
@ 2020-04-22  9:05 ` Rafael J. Wysocki
  2020-04-22 11:18   ` Chunyan Zhang
  0 siblings, 1 reply; 5+ messages in thread
From: Rafael J. Wysocki @ 2020-04-22  9:05 UTC (permalink / raw)
  To: Chunyan Zhang
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Len Brown, Pavel Machek,
	Linux PM, Linux Kernel Mailing List, Orson Zhai, Vincent Wang,
	Samer Xie, Chunyan Zhang

On Wed, Apr 22, 2020 at 7:15 AM Chunyan Zhang <zhang.lyra@gmail.com> wrote:
>
> From: Vincent Wang <vincent.wang@unisoc.com>
>
> If dpm_prepare() fails in dpm_suspend_start(), dpm_suspend() can't be
> called.

That's correct.

> And then, devfreq_suspend() and cpufreq_suspend() will not be
> called in the suspend flow.

Right.

> But in the resiume flow, devfreq_resume() and cpufreq_resume() will
> be called.

Right, and they are expected to cope with the situation.

> This patch will ensure that devfreq_suspend/devfreq_resume and
> cpufreq_suspend/cpufreq_resume are called in pairs.

So why is it better to do this than to make devfreq_resume() meet the
expectations?

> Signed-off-by: Vincent Wang <vincent.wang@unisoc.com>
> Signed-off-by: Samer Xie <samer.xie@unisoc.com>
> Signed-off-by: Chunyan Zhang <zhang.lyra@gmail.com>
> ---
>  drivers/base/power/main.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
> index fdd508a78ffd..eb3d987d43e0 100644
> --- a/drivers/base/power/main.c
> +++ b/drivers/base/power/main.c
> @@ -1866,9 +1866,6 @@ int dpm_suspend(pm_message_t state)
>         trace_suspend_resume(TPS("dpm_suspend"), state.event, true);
>         might_sleep();
>
> -       devfreq_suspend();
> -       cpufreq_suspend();
> -
>         mutex_lock(&dpm_list_mtx);
>         pm_transition = state;
>         async_error = 0;
> @@ -1988,6 +1985,9 @@ int dpm_prepare(pm_message_t state)
>         trace_suspend_resume(TPS("dpm_prepare"), state.event, true);
>         might_sleep();
>
> +       devfreq_suspend();
> +       cpufreq_suspend();
> +
>         /*
>          * Give a chance for the known devices to complete their probes, before
>          * disable probing of devices. This sync point is important at least
> --
> 2.20.1
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] PM: sleep: call devfreq_suspend/resume and cpufreq_suspend/resume in pairs.
  2020-04-22  9:05 ` Rafael J. Wysocki
@ 2020-04-22 11:18   ` Chunyan Zhang
  2020-04-22 14:21     ` Rafael J. Wysocki
  0 siblings, 1 reply; 5+ messages in thread
From: Chunyan Zhang @ 2020-04-22 11:18 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Len Brown, Pavel Machek,
	Linux PM, Linux Kernel Mailing List, Orson Zhai, Vincent Wang,
	Samer Xie, Chunyan Zhang

Hi Rafael,

(Behalf Of Vincent Wang)

Thanks for your comments, please see my answers below.

On Wed, 22 Apr 2020 at 17:05, Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> On Wed, Apr 22, 2020 at 7:15 AM Chunyan Zhang <zhang.lyra@gmail.com> wrote:
> >
> > From: Vincent Wang <vincent.wang@unisoc.com>
> >
> > If dpm_prepare() fails in dpm_suspend_start(), dpm_suspend() can't be
> > called.
>
> That's correct.
>
> > And then, devfreq_suspend() and cpufreq_suspend() will not be
> > called in the suspend flow.
>
> Right.
>
> > But in the resiume flow, devfreq_resume() and cpufreq_resume() will
> > be called.
>
> Right, and they are expected to cope with the situation.
>
> > This patch will ensure that devfreq_suspend/devfreq_resume and
> > cpufreq_suspend/cpufreq_resume are called in pairs.
>
> So why is it better to do this than to make devfreq_resume() meet the
> expectations?

Yes,we found an issue with cpufreq schedutil governor on kernel4.14,
and I think the issue should haven't been changed on the latest
version of kernel.

In the function dpm_suspend_start(), dpm_suspend() would not be
exceuted if return error from device_prepare() [1]. So
cpufreq_cpufreq() will not be called, then
cpufreq_remove_update_util_hook() will not be called either, and so
cpufreq_update_util_data will not be NULL.

In the dpm resume flow, sugov_start() will be called, in which
sg_cpu.update_util will be set to 0.

And since cpufreq_update_util_data is not NULL, data->func will not be
set and is still NULL which actually is sg_cpu.update_util.

void cpufreq_add_update_util_hook(int cpu, struct update_util_data *data,
                        void (*func)(struct update_util_data *data, u64 time,
                                     unsigned int flags))
{
[...]
        if (WARN_ON(per_cpu(cpufreq_update_util_data, cpu)))
                return;

        data->func = func;
[...]
}

When cpufreq_update_util() is called by scheduler, there will be a
NULL pointer issue.


[1] https://elixir.bootlin.com/linux/v5.7-rc1/source/drivers/base/power/main.c#L2052


>
> > Signed-off-by: Vincent Wang <vincent.wang@unisoc.com>
> > Signed-off-by: Samer Xie <samer.xie@unisoc.com>
> > Signed-off-by: Chunyan Zhang <zhang.lyra@gmail.com>
> > ---
> >  drivers/base/power/main.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
> > index fdd508a78ffd..eb3d987d43e0 100644
> > --- a/drivers/base/power/main.c
> > +++ b/drivers/base/power/main.c
> > @@ -1866,9 +1866,6 @@ int dpm_suspend(pm_message_t state)
> >         trace_suspend_resume(TPS("dpm_suspend"), state.event, true);
> >         might_sleep();
> >
> > -       devfreq_suspend();
> > -       cpufreq_suspend();
> > -
> >         mutex_lock(&dpm_list_mtx);
> >         pm_transition = state;
> >         async_error = 0;
> > @@ -1988,6 +1985,9 @@ int dpm_prepare(pm_message_t state)
> >         trace_suspend_resume(TPS("dpm_prepare"), state.event, true);
> >         might_sleep();
> >
> > +       devfreq_suspend();
> > +       cpufreq_suspend();
> > +
> >         /*
> >          * Give a chance for the known devices to complete their probes, before
> >          * disable probing of devices. This sync point is important at least
> > --
> > 2.20.1
> >

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] PM: sleep: call devfreq_suspend/resume and cpufreq_suspend/resume in pairs.
  2020-04-22 11:18   ` Chunyan Zhang
@ 2020-04-22 14:21     ` Rafael J. Wysocki
  2020-04-23  2:41       ` Chunyan Zhang
  0 siblings, 1 reply; 5+ messages in thread
From: Rafael J. Wysocki @ 2020-04-22 14:21 UTC (permalink / raw)
  To: Chunyan Zhang
  Cc: Rafael J. Wysocki, Rafael J . Wysocki, Greg Kroah-Hartman,
	Len Brown, Pavel Machek, Linux PM, Linux Kernel Mailing List,
	Orson Zhai, Vincent Wang, Samer Xie, Chunyan Zhang

On Wed, Apr 22, 2020 at 1:19 PM Chunyan Zhang <zhang.lyra@gmail.com> wrote:
>
> Hi Rafael,
>
> (Behalf Of Vincent Wang)
>
> Thanks for your comments, please see my answers below.
>
> On Wed, 22 Apr 2020 at 17:05, Rafael J. Wysocki <rafael@kernel.org> wrote:
> >
> > On Wed, Apr 22, 2020 at 7:15 AM Chunyan Zhang <zhang.lyra@gmail.com> wrote:
> > >
> > > From: Vincent Wang <vincent.wang@unisoc.com>
> > >
> > > If dpm_prepare() fails in dpm_suspend_start(), dpm_suspend() can't be
> > > called.
> >
> > That's correct.
> >
> > > And then, devfreq_suspend() and cpufreq_suspend() will not be
> > > called in the suspend flow.
> >
> > Right.
> >
> > > But in the resiume flow, devfreq_resume() and cpufreq_resume() will
> > > be called.
> >
> > Right, and they are expected to cope with the situation.
> >
> > > This patch will ensure that devfreq_suspend/devfreq_resume and
> > > cpufreq_suspend/cpufreq_resume are called in pairs.
> >
> > So why is it better to do this than to make devfreq_resume() meet the
> > expectations?
>
> Yes,we found an issue with cpufreq schedutil governor on kernel4.14,
> and I think the issue should haven't been changed on the latest
> version of kernel.
>
> In the function dpm_suspend_start(), dpm_suspend() would not be
> exceuted if return error from device_prepare() [1]. So
> cpufreq_cpufreq() will not be called,

I guess you mean cpufreq_suspend().

That should be OK .

> then cpufreq_remove_update_util_hook() will not be called either, and so
> cpufreq_update_util_data will not be NULL.
>
> In the dpm resume flow, sugov_start() will be called, in which
> sg_cpu.update_util will be set to 0.

Which code patch does this?

Surely not cpufreq_resume(), because that checks cpufreq_suspended which
cannot be set if cpufreq_suspend() has not been called (because it is the only
place setting cpufreq_suspended).

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] PM: sleep: call devfreq_suspend/resume and cpufreq_suspend/resume in pairs.
  2020-04-22 14:21     ` Rafael J. Wysocki
@ 2020-04-23  2:41       ` Chunyan Zhang
  0 siblings, 0 replies; 5+ messages in thread
From: Chunyan Zhang @ 2020-04-23  2:41 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Len Brown, Pavel Machek,
	Linux PM, Linux Kernel Mailing List, Orson Zhai, Vincent Wang,
	Samer Xie, Chunyan Zhang

On Wed, 22 Apr 2020 at 22:21, Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> On Wed, Apr 22, 2020 at 1:19 PM Chunyan Zhang <zhang.lyra@gmail.com> wrote:
> >
> > Hi Rafael,
> >
> > (Behalf Of Vincent Wang)
> >
> > Thanks for your comments, please see my answers below.
> >
> > On Wed, 22 Apr 2020 at 17:05, Rafael J. Wysocki <rafael@kernel.org> wrote:
> > >
> > > On Wed, Apr 22, 2020 at 7:15 AM Chunyan Zhang <zhang.lyra@gmail.com> wrote:
> > > >
> > > > From: Vincent Wang <vincent.wang@unisoc.com>
> > > >
> > > > If dpm_prepare() fails in dpm_suspend_start(), dpm_suspend() can't be
> > > > called.
> > >
> > > That's correct.
> > >
> > > > And then, devfreq_suspend() and cpufreq_suspend() will not be
> > > > called in the suspend flow.
> > >
> > > Right.
> > >
> > > > But in the resiume flow, devfreq_resume() and cpufreq_resume() will
> > > > be called.
> > >
> > > Right, and they are expected to cope with the situation.
> > >
> > > > This patch will ensure that devfreq_suspend/devfreq_resume and
> > > > cpufreq_suspend/cpufreq_resume are called in pairs.
> > >
> > > So why is it better to do this than to make devfreq_resume() meet the
> > > expectations?
> >
> > Yes,we found an issue with cpufreq schedutil governor on kernel4.14,
> > and I think the issue should haven't been changed on the latest
> > version of kernel.
> >
> > In the function dpm_suspend_start(), dpm_suspend() would not be
> > exceuted if return error from device_prepare() [1]. So
> > cpufreq_cpufreq() will not be called,
>
> I guess you mean cpufreq_suspend().
>
> That should be OK .
>
> > then cpufreq_remove_update_util_hook() will not be called either, and so
> > cpufreq_update_util_data will not be NULL.
> >
> > In the dpm resume flow, sugov_start() will be called, in which
> > sg_cpu.update_util will be set to 0.
>
> Which code patch does this?
>
> Surely not cpufreq_resume(), because that checks cpufreq_suspended which
> cannot be set if cpufreq_suspend() has not been called (because it is the only
> place setting cpufreq_suspended).

Right, I saw that, then there's no issue indeed. I just need to
backport the patch which added checking of cpufreq_suspended to
cpufreq_resume.

Thanks for your review!

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-04-23  2:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-22  5:15 [PATCH] PM: sleep: call devfreq_suspend/resume and cpufreq_suspend/resume in pairs Chunyan Zhang
2020-04-22  9:05 ` Rafael J. Wysocki
2020-04-22 11:18   ` Chunyan Zhang
2020-04-22 14:21     ` Rafael J. Wysocki
2020-04-23  2:41       ` Chunyan Zhang

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).