]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.14.16/sched_clock-avoid-corrupting-hrtimer-tree-during-suspend.patch
drop queue-4.14/mips-make-sure-dt-memory-regions-are-valid.patch
[thirdparty/kernel/stable-queue.git] / releases / 3.14.16 / sched_clock-avoid-corrupting-hrtimer-tree-during-suspend.patch
CommitLineData
d4cb193b
GKH
1From f723aa1817dd8f4fe005aab52ba70c8ab0ef9457 Mon Sep 17 00:00:00 2001
2From: Stephen Boyd <sboyd@codeaurora.org>
3Date: Wed, 23 Jul 2014 21:03:50 -0700
4Subject: sched_clock: Avoid corrupting hrtimer tree during suspend
5
6From: Stephen Boyd <sboyd@codeaurora.org>
7
8commit f723aa1817dd8f4fe005aab52ba70c8ab0ef9457 upstream.
9
10During suspend we call sched_clock_poll() to update the epoch and
11accumulated time and reprogram the sched_clock_timer to fire
12before the next wrap-around time. Unfortunately,
13sched_clock_poll() doesn't restart the timer, instead it relies
14on the hrtimer layer to do that and during suspend we aren't
15calling that function from the hrtimer layer. Instead, we're
16reprogramming the expires time while the hrtimer is enqueued,
17which can cause the hrtimer tree to be corrupted. Furthermore, we
18restart the timer during suspend but we update the epoch during
19resume which seems counter-intuitive.
20
21Let's fix this by saving the accumulated state and canceling the
22timer during suspend. On resume we can update the epoch and
23restart the timer similar to what we would do if we were starting
24the clock for the first time.
25
26Fixes: a08ca5d1089d "sched_clock: Use an hrtimer instead of timer"
27Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
28Signed-off-by: John Stultz <john.stultz@linaro.org>
29Link: http://lkml.kernel.org/r/1406174630-23458-1-git-send-email-john.stultz@linaro.org
30Cc: Ingo Molnar <mingo@kernel.org>
31Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
32Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
33
34---
35 kernel/time/sched_clock.c | 4 +++-
36 1 file changed, 3 insertions(+), 1 deletion(-)
37
38--- a/kernel/time/sched_clock.c
39+++ b/kernel/time/sched_clock.c
40@@ -204,7 +204,8 @@ void __init sched_clock_postinit(void)
41
42 static int sched_clock_suspend(void)
43 {
44- sched_clock_poll(&sched_clock_timer);
45+ update_sched_clock();
46+ hrtimer_cancel(&sched_clock_timer);
47 cd.suspended = true;
48 return 0;
49 }
50@@ -212,6 +213,7 @@ static int sched_clock_suspend(void)
51 static void sched_clock_resume(void)
52 {
53 cd.epoch_cyc = read_sched_clock();
54+ hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL);
55 cd.suspended = false;
56 }
57