summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-07-08 06:46:48 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-08 06:46:48 +0300
commitc09230f30876589e246c83a4b4649e60534638cf (patch)
treed7543c83ee092bc386a261ab730eabe8f69705ec /drivers
parentac904ae6e6f0a56be7b9a1cf66fbd50dd025fb06 (diff)
parent7fe39a21557b251e101671f2c3f79558a756afef (diff)
downloadlinux-c09230f30876589e246c83a4b4649e60534638cf.tar.xz
Merge tag 'pm-4.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "One fix for a recent cpuidle core change that, against all odds, introduced a functional regression on Power systems and the fix for the crash during resume from hibernation on x86-64 that has been in the works for the last few weeks (it actually was ready last week, but I wanted to allow the reporters to test if for some more time). Specifics: - Fix a recent performance regression on Power systems (powernv and pseries) introduced by a core cpuidle commit that decreased the precision of the last_residency conversion from nano- to microseconds, which should not matter in theory, but turned out to play not-so-well with the special "snooze" idle state on Power (Shreyas B Prabhu). - Fix a crash during resume from hibernation on x86-64 caused by possible corruption of the kernel text part of page tables in the last phase of image restoration exposed by a security-related change during the 4.3 development cycle (Rafael Wysocki)" * tag 'pm-4.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: cpuidle: Fix last_residency division x86/power/64: Fix kernel text mapping corruption during image restoration
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpuidle/cpuidle.c12
1 files changed, 4 insertions, 8 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index a4d0059e232c..c73207abb5a4 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -173,7 +173,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
struct cpuidle_state *target_state = &drv->states[index];
bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
- u64 time_start, time_end;
+ ktime_t time_start, time_end;
s64 diff;
/*
@@ -195,13 +195,13 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
sched_idle_set_state(target_state);
trace_cpu_idle_rcuidle(index, dev->cpu);
- time_start = local_clock();
+ time_start = ns_to_ktime(local_clock());
stop_critical_timings();
entered_state = target_state->enter(dev, drv, index);
start_critical_timings();
- time_end = local_clock();
+ time_end = ns_to_ktime(local_clock());
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
/* The cpu is no longer idle or about to enter idle. */
@@ -217,11 +217,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
if (!cpuidle_state_is_coupled(drv, index))
local_irq_enable();
- /*
- * local_clock() returns the time in nanosecond, let's shift
- * by 10 (divide by 1024) to have microsecond based time.
- */
- diff = (time_end - time_start) >> 10;
+ diff = ktime_us_delta(time_end, time_start);
if (diff > INT_MAX)
diff = INT_MAX;