Skip to contentSkip to conversation

Patch "cpuidle: Fix cpuidle_state_is_coupled() argument in cpuidle_enter()" has been added to the 4.6-stable tree

PATCH [email protected] 1 participant 1 message Jun 4, 2016

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

cpuidle: Fix cpuidle_state_is_coupled() argument in cpuidle_enter()

to the 4.6-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
cpuidle-fix-cpuidle_state_is_coupled-argument-in-cpuidle_enter.patch
and it can be found in the queue-4.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From e7387da52028b072489c45efeb7a916c0205ebd2 Mon Sep 17 00:00:00 2001

From: Daniel Lezcano <[email protected]>
Date: Tue, 17 May 2016 16:54:00 +0200
Subject: cpuidle: Fix cpuidle_state_is_coupled() argument in cpuidle_enter()

From: Daniel Lezcano <[email protected]>

commit e7387da52028b072489c45efeb7a916c0205ebd2 upstream.

Commit 0b89e9aa2856 (cpuidle: delay enabling interrupts until all coupled CPUs leave idle) rightfully fixed a regression by letting the coupled idle state framework to handle local interrupt enabling when the CPU is exiting an idle state.

The current code checks if the idle state is coupled and, if so, it will let the coupled code to enable interrupts. This way, it can decrement the ready-count before handling the interrupt. This mechanism prevents the other CPUs from waiting for a CPU which is handling interrupts.

But the check is done against the state index returned by the back end driver's ->enter functions which could be different from the initial index passed as parameter to the cpuidle_enter_state() function.

entered_state = target_state->enter(dev, drv, index);

[ ... ]

if (!cpuidle_state_is_coupled(drv, entered_state))

	local_irq_enable();

[ ... ]

If the 'index' is referring to a coupled idle state but the 'entered_state' is *not* coupled, then the interrupts are enabled again. All CPUs blocked on the sync barrier may busy loop longer if the CPU has interrupts to handle before decrementing the ready-count. That's consuming more energy than saving.

Fixes 0b89e9aa2856 (cpuidle: delay enabling interrupts until all coupled CPUs leave idle)
[ rjw: Subject & changelog ]
---
 drivers/cpuidle/cpuidle.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpuidle/cpuidle.c +1 -1
@@ -214,7 +214,7 @@ int cpuidle_enter_state(struct cpuidle_d
 		tick_broadcast_exit();
 	}
 
-	if (!cpuidle_state_is_coupled(drv, entered_state))
+	if (!cpuidle_state_is_coupled(drv, index))
 		local_irq_enable();
 
 	diff = ktime_to_us(ktime_sub(time_end, time_start));

Patches currently in stable-queue which might be from [email protected] are

queue-4.6/cpuidle-fix-cpuidle_state_is_coupled-argument-in-cpuidle_enter.patch queue-4.6/cpuidle-indicate-when-a-device-has-been-unregistered.patch