From f65ee094eda6e5897172a1276ffee88cf5489928 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 15 Nov 2024 21:58:31 +0100 Subject: [PATCH] cpuidle: Do not return from cpuidle_play_dead() on callback failures 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. Also notice that the :enter_dead() state callback is not expected to return on success (the CPU should be "dead" then), so make cpuidle_play_dead() ignore its return value. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mario Limonciello Tested-by: Mario Limonciello # 6.12-rc7 Reviewed-by: Gautham R. Shenoy Link: https://patch.msgid.link/3318440.aeNJFYEL58@rjwysocki.net --- drivers/cpuidle/cpuidle.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 06ace16f9e71..0835da449db8 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -69,11 +69,15 @@ int cpuidle_play_dead(void) if (!drv) return -ENODEV; - /* Find lowest-power state that supports long-term idle */ - for (i = drv->state_count - 1; i >= 0; i--) + for (i = drv->state_count - 1; i >= 0; i--) { if (drv->states[i].enter_dead) - return drv->states[i].enter_dead(dev, i); + drv->states[i].enter_dead(dev, i); + } + /* + * If :enter_dead() is successful, it will never return, so reaching + * here means that all of them failed above or were not present. + */ return -ENODEV; } -- 2.20.1