lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1463496840-2858-1-git-send-email-daniel.lezcano@linaro.org>
Date:	Tue, 17 May 2016 16:54:00 +0200
From:	Daniel Lezcano <daniel.lezcano@...aro.org>
To:	rjw@...ysocki.net
Cc:	gregory.clement@...e-electrons.com, linux-pm@...r.kernel.org,
	linux@...linux.org.uk, paul.burton@...tec.com,
	stable@...r.kernel.org, linux-kernel@...r.kernel.org (open list)
Subject: [PATCH] cpuidle: Fix coupled state parameter in cpuidle_enter()

The commit 0b89e9aa2856 rightfully fixed a regression by letting the couple
idle state framework to handle local interrupt enabling when the cpu is
exiting an idle state.

The current code check if the idle state is a coupled one and, if so, it will
let the couple code to enable the interrupt. This way, it can decrement the
ready-count before handling the interrupts. This mechanism prevents the other
cpus to wait for a cpu which is handling interrupts.

But the check is done against the state index returned by the back end driver
'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. Thus consuming more energy than saving.

Fixes: 0b89e9aa2856 "cpuidle: delay enabling interrupts until all coupled CPUs leave idle"
Cc: stable@...r.kernel.org
Signed-off-by: Daniel Lezcano <daniel.lezcano@...aro.org>
---
 drivers/cpuidle/cpuidle.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index f996efc..cd021ed 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -214,7 +214,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
 		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));
-- 
1.9.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ