* [PATCH v1] cpuidle: Do not return from cpuidle_play_dead() on callback failures
@ 2024-11-14 17:46 Rafael J. Wysocki
2024-11-15 3:22 ` Mario Limonciello
2024-11-15 10:14 ` Peter Zijlstra
0 siblings, 2 replies; 7+ messages in thread
From: Rafael J. Wysocki @ 2024-11-14 17:46 UTC (permalink / raw)
To: Linux PM
Cc: LKML, x86 Maintainers, Peter Zijlstra, Patryk Wlazlyn,
Gautham R. Shenoy, Artem Bityutskiy, Mario Limonciello
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
If the :enter_dead() idle state callback fails for a certain state,
there may be still a shallower state for which it will work.
Because the only caller of cpuidle_play_dead(), native_play_dead(),
falls back to hlt_play_dead() if it returns an error, it should
better try all of the idle states for which :enter_dead() is present
before failing, so change it accordingly.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/cpuidle/cpuidle.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
Index: linux-pm/drivers/cpuidle/cpuidle.c
===================================================================
--- linux-pm.orig/drivers/cpuidle/cpuidle.c
+++ linux-pm/drivers/cpuidle/cpuidle.c
@@ -70,9 +70,10 @@ int cpuidle_play_dead(void)
return -ENODEV;
/* Find lowest-power state that supports long-term idle */
- for (i = drv->state_count - 1; i >= 0; i--)
- if (drv->states[i].enter_dead)
- return drv->states[i].enter_dead(dev, i);
+ for (i = drv->state_count - 1; i >= 0; i--) {
+ if (drv->states[i].enter_dead && !drv->states[i].enter_dead(dev, i))
+ return 0;
+ }
return -ENODEV;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1] cpuidle: Do not return from cpuidle_play_dead() on callback failures
2024-11-14 17:46 [PATCH v1] cpuidle: Do not return from cpuidle_play_dead() on callback failures Rafael J. Wysocki
@ 2024-11-15 3:22 ` Mario Limonciello
2024-11-15 10:14 ` Peter Zijlstra
1 sibling, 0 replies; 7+ messages in thread
From: Mario Limonciello @ 2024-11-15 3:22 UTC (permalink / raw)
To: Rafael J. Wysocki, Linux PM
Cc: LKML, x86 Maintainers, Peter Zijlstra, Patryk Wlazlyn,
Gautham R. Shenoy, Artem Bityutskiy
On 11/14/2024 11:46, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> If the :enter_dead() idle state callback fails for a certain state,
> there may be still a shallower state for which it will work.
>
> Because the only caller of cpuidle_play_dead(), native_play_dead(),
> falls back to hlt_play_dead() if it returns an error, it should
> better try all of the idle states for which :enter_dead() is present
> before failing, so change it accordingly.
>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Tested-by: Mario Limonciello <mario.limonciello@amd.com> # 6.12-rc7
> ---
> drivers/cpuidle/cpuidle.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> Index: linux-pm/drivers/cpuidle/cpuidle.c
> ===================================================================
> --- linux-pm.orig/drivers/cpuidle/cpuidle.c
> +++ linux-pm/drivers/cpuidle/cpuidle.c
> @@ -70,9 +70,10 @@ int cpuidle_play_dead(void)
> return -ENODEV;
>
> /* Find lowest-power state that supports long-term idle */
> - for (i = drv->state_count - 1; i >= 0; i--)
> - if (drv->states[i].enter_dead)
> - return drv->states[i].enter_dead(dev, i);
> + for (i = drv->state_count - 1; i >= 0; i--) {
> + if (drv->states[i].enter_dead && !drv->states[i].enter_dead(dev, i))
> + return 0;
> + }
>
> return -ENODEV;
> }
>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1] cpuidle: Do not return from cpuidle_play_dead() on callback failures
2024-11-14 17:46 [PATCH v1] cpuidle: Do not return from cpuidle_play_dead() on callback failures Rafael J. Wysocki
2024-11-15 3:22 ` Mario Limonciello
@ 2024-11-15 10:14 ` Peter Zijlstra
2024-11-15 12:46 ` Rafael J. Wysocki
1 sibling, 1 reply; 7+ messages in thread
From: Peter Zijlstra @ 2024-11-15 10:14 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM, LKML, x86 Maintainers, Patryk Wlazlyn,
Gautham R. Shenoy, Artem Bityutskiy, Mario Limonciello
On Thu, Nov 14, 2024 at 06:46:20PM +0100, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> If the :enter_dead() idle state callback fails for a certain state,
> there may be still a shallower state for which it will work.
>
> Because the only caller of cpuidle_play_dead(), native_play_dead(),
> falls back to hlt_play_dead() if it returns an error, it should
> better try all of the idle states for which :enter_dead() is present
> before failing, so change it accordingly.
>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
> drivers/cpuidle/cpuidle.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> Index: linux-pm/drivers/cpuidle/cpuidle.c
> ===================================================================
> --- linux-pm.orig/drivers/cpuidle/cpuidle.c
> +++ linux-pm/drivers/cpuidle/cpuidle.c
> @@ -70,9 +70,10 @@ int cpuidle_play_dead(void)
> return -ENODEV;
>
> /* Find lowest-power state that supports long-term idle */
> - for (i = drv->state_count - 1; i >= 0; i--)
> - if (drv->states[i].enter_dead)
> - return drv->states[i].enter_dead(dev, i);
> + for (i = drv->state_count - 1; i >= 0; i--) {
> + if (drv->states[i].enter_dead && !drv->states[i].enter_dead(dev, i))
> + return 0;
> + }
Hmm, strictly speaking there is no 'success' return from play_dead(). On
success, the CPU is dead :-)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1] cpuidle: Do not return from cpuidle_play_dead() on callback failures
2024-11-15 10:14 ` Peter Zijlstra
@ 2024-11-15 12:46 ` Rafael J. Wysocki
2024-11-15 12:55 ` Peter Zijlstra
0 siblings, 1 reply; 7+ messages in thread
From: Rafael J. Wysocki @ 2024-11-15 12:46 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Rafael J. Wysocki, Linux PM, LKML, x86 Maintainers,
Patryk Wlazlyn, Gautham R. Shenoy, Artem Bityutskiy,
Mario Limonciello
On Fri, Nov 15, 2024 at 11:14 AM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Thu, Nov 14, 2024 at 06:46:20PM +0100, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > If the :enter_dead() idle state callback fails for a certain state,
> > there may be still a shallower state for which it will work.
> >
> > Because the only caller of cpuidle_play_dead(), native_play_dead(),
> > falls back to hlt_play_dead() if it returns an error, it should
> > better try all of the idle states for which :enter_dead() is present
> > before failing, so change it accordingly.
> >
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> > drivers/cpuidle/cpuidle.c | 7 ++++---
> > 1 file changed, 4 insertions(+), 3 deletions(-)
> >
> > Index: linux-pm/drivers/cpuidle/cpuidle.c
> > ===================================================================
> > --- linux-pm.orig/drivers/cpuidle/cpuidle.c
> > +++ linux-pm/drivers/cpuidle/cpuidle.c
> > @@ -70,9 +70,10 @@ int cpuidle_play_dead(void)
> > return -ENODEV;
> >
> > /* Find lowest-power state that supports long-term idle */
> > - for (i = drv->state_count - 1; i >= 0; i--)
> > - if (drv->states[i].enter_dead)
> > - return drv->states[i].enter_dead(dev, i);
> > + for (i = drv->state_count - 1; i >= 0; i--) {
> > + if (drv->states[i].enter_dead && !drv->states[i].enter_dead(dev, i))
> > + return 0;
> > + }
>
> Hmm, strictly speaking there is no 'success' return from play_dead(). On
> success, the CPU is dead :-)
Well, would you prefer something like
for (i = drv->state_count - 1; i >= 0; i--) {
if (drv->states[i].enter_dead)
drv->states[i].enter_dead(dev, i);
}
and adding a comment before the final return statement that
:enter_dead() only returns on failure?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1] cpuidle: Do not return from cpuidle_play_dead() on callback failures
2024-11-15 12:46 ` Rafael J. Wysocki
@ 2024-11-15 12:55 ` Peter Zijlstra
2024-11-15 13:25 ` Rafael J. Wysocki
0 siblings, 1 reply; 7+ messages in thread
From: Peter Zijlstra @ 2024-11-15 12:55 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Rafael J. Wysocki, Linux PM, LKML, x86 Maintainers,
Patryk Wlazlyn, Gautham R. Shenoy, Artem Bityutskiy,
Mario Limonciello
On Fri, Nov 15, 2024 at 01:46:29PM +0100, Rafael J. Wysocki wrote:
> On Fri, Nov 15, 2024 at 11:14 AM Peter Zijlstra <peterz@infradead.org> wrote:
> >
> > On Thu, Nov 14, 2024 at 06:46:20PM +0100, Rafael J. Wysocki wrote:
> > > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > >
> > > If the :enter_dead() idle state callback fails for a certain state,
> > > there may be still a shallower state for which it will work.
> > >
> > > Because the only caller of cpuidle_play_dead(), native_play_dead(),
> > > falls back to hlt_play_dead() if it returns an error, it should
> > > better try all of the idle states for which :enter_dead() is present
> > > before failing, so change it accordingly.
> > >
> > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > ---
> > > drivers/cpuidle/cpuidle.c | 7 ++++---
> > > 1 file changed, 4 insertions(+), 3 deletions(-)
> > >
> > > Index: linux-pm/drivers/cpuidle/cpuidle.c
> > > ===================================================================
> > > --- linux-pm.orig/drivers/cpuidle/cpuidle.c
> > > +++ linux-pm/drivers/cpuidle/cpuidle.c
> > > @@ -70,9 +70,10 @@ int cpuidle_play_dead(void)
> > > return -ENODEV;
> > >
> > > /* Find lowest-power state that supports long-term idle */
> > > - for (i = drv->state_count - 1; i >= 0; i--)
> > > - if (drv->states[i].enter_dead)
> > > - return drv->states[i].enter_dead(dev, i);
> > > + for (i = drv->state_count - 1; i >= 0; i--) {
> > > + if (drv->states[i].enter_dead && !drv->states[i].enter_dead(dev, i))
> > > + return 0;
> > > + }
> >
> > Hmm, strictly speaking there is no 'success' return from play_dead(). On
> > success, the CPU is dead :-)
>
> Well, would you prefer something like
>
> for (i = drv->state_count - 1; i >= 0; i--) {
> if (drv->states[i].enter_dead)
> drv->states[i].enter_dead(dev, i);
> }
>
> and adding a comment before the final return statement that
> :enter_dead() only returns on failure?
Yeah, but perhaps remove the return value entirely if we're going to
ignore it anyway. And then assume that any return is a failure to die.
I mean, something like:
if (drv->states[i].enter_dead && !drv->states[i].enter_dead(dev, i))
panic("Dead CPU walking...");
is 'fun' but not very useful.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1] cpuidle: Do not return from cpuidle_play_dead() on callback failures
2024-11-15 12:55 ` Peter Zijlstra
@ 2024-11-15 13:25 ` Rafael J. Wysocki
2024-11-15 17:40 ` Peter Zijlstra
0 siblings, 1 reply; 7+ messages in thread
From: Rafael J. Wysocki @ 2024-11-15 13:25 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Rafael J. Wysocki, Linux PM, LKML, x86 Maintainers,
Patryk Wlazlyn, Gautham R. Shenoy, Artem Bityutskiy,
Mario Limonciello
On Fri, Nov 15, 2024 at 1:55 PM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Fri, Nov 15, 2024 at 01:46:29PM +0100, Rafael J. Wysocki wrote:
> > On Fri, Nov 15, 2024 at 11:14 AM Peter Zijlstra <peterz@infradead.org> wrote:
> > >
> > > On Thu, Nov 14, 2024 at 06:46:20PM +0100, Rafael J. Wysocki wrote:
> > > > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > >
> > > > If the :enter_dead() idle state callback fails for a certain state,
> > > > there may be still a shallower state for which it will work.
> > > >
> > > > Because the only caller of cpuidle_play_dead(), native_play_dead(),
> > > > falls back to hlt_play_dead() if it returns an error, it should
> > > > better try all of the idle states for which :enter_dead() is present
> > > > before failing, so change it accordingly.
> > > >
> > > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > > ---
> > > > drivers/cpuidle/cpuidle.c | 7 ++++---
> > > > 1 file changed, 4 insertions(+), 3 deletions(-)
> > > >
> > > > Index: linux-pm/drivers/cpuidle/cpuidle.c
> > > > ===================================================================
> > > > --- linux-pm.orig/drivers/cpuidle/cpuidle.c
> > > > +++ linux-pm/drivers/cpuidle/cpuidle.c
> > > > @@ -70,9 +70,10 @@ int cpuidle_play_dead(void)
> > > > return -ENODEV;
> > > >
> > > > /* Find lowest-power state that supports long-term idle */
> > > > - for (i = drv->state_count - 1; i >= 0; i--)
> > > > - if (drv->states[i].enter_dead)
> > > > - return drv->states[i].enter_dead(dev, i);
> > > > + for (i = drv->state_count - 1; i >= 0; i--) {
> > > > + if (drv->states[i].enter_dead && !drv->states[i].enter_dead(dev, i))
> > > > + return 0;
> > > > + }
> > >
> > > Hmm, strictly speaking there is no 'success' return from play_dead(). On
> > > success, the CPU is dead :-)
> >
> > Well, would you prefer something like
> >
> > for (i = drv->state_count - 1; i >= 0; i--) {
> > if (drv->states[i].enter_dead)
> > drv->states[i].enter_dead(dev, i);
> > }
> >
> > and adding a comment before the final return statement that
> > :enter_dead() only returns on failure?
>
> Yeah, but perhaps remove the return value entirely if we're going to
> ignore it anyway. And then assume that any return is a failure to die.
>
> I mean, something like:
>
> if (drv->states[i].enter_dead && !drv->states[i].enter_dead(dev, i))
> panic("Dead CPU walking...");
>
> is 'fun' but not very useful.
The panic would be hard to debug if it ever triggers I'm afraid and
there is the fallback to HLT in the caller.
An error message could be printed here though:
if (drv->states[i].enter_dead && !drv->states[i].enter_dead(dev, i))
pr_err("CPU %d: Unexpectedly undead\n", dev->cpu);
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1] cpuidle: Do not return from cpuidle_play_dead() on callback failures
2024-11-15 13:25 ` Rafael J. Wysocki
@ 2024-11-15 17:40 ` Peter Zijlstra
0 siblings, 0 replies; 7+ messages in thread
From: Peter Zijlstra @ 2024-11-15 17:40 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Rafael J. Wysocki, Linux PM, LKML, x86 Maintainers,
Patryk Wlazlyn, Gautham R. Shenoy, Artem Bityutskiy,
Mario Limonciello
On Fri, Nov 15, 2024 at 02:25:23PM +0100, Rafael J. Wysocki wrote:
> > I mean, something like:
> >
> > if (drv->states[i].enter_dead && !drv->states[i].enter_dead(dev, i))
> > panic("Dead CPU walking...");
> >
> > is 'fun' but not very useful.
>
> The panic would be hard to debug if it ever triggers I'm afraid and
> there is the fallback to HLT in the caller.
I was being facetious, removing the return value and simply calling them
all in reverse order is fine.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-11-15 17:40 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-14 17:46 [PATCH v1] cpuidle: Do not return from cpuidle_play_dead() on callback failures Rafael J. Wysocki
2024-11-15 3:22 ` Mario Limonciello
2024-11-15 10:14 ` Peter Zijlstra
2024-11-15 12:46 ` Rafael J. Wysocki
2024-11-15 12:55 ` Peter Zijlstra
2024-11-15 13:25 ` Rafael J. Wysocki
2024-11-15 17:40 ` Peter Zijlstra
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).