timers, sched/clock: Hook into s2idle freeze path

The sched_clock() suspend/resume callbacks are called from a
syscore_ops structure that's registered after the timekeeping
syscore_ops. With the suspend-to-idle method of suspend we will
freeze the tick and timekeeping subsystem, but we don't suspend
the sched clock here, because syscore ops are not called in
suspend to idle. Hook this up directly in the timekeeping freeze
path when we go idle on the last CPU. This way, the sched clock
doesn't jump across a suspend/resume cycle.

Change-Id: I2ea488dce7186d6210d3af34b0e1a67c9f1cdf78
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
This commit is contained in:
Stephen Boyd 2017-08-11 14:23:19 -07:00 committed by Maulik Shah
parent f7dae0b5f5
commit 12242fff55
3 changed files with 9 additions and 2 deletions

View File

@ -13,6 +13,8 @@ extern void sched_clock_postinit(void);
extern void sched_clock_register(u64 (*read)(void), int bits,
unsigned long rate);
extern int sched_clock_suspend(void);
extern void sched_clock_resume(void);
#else
static inline void sched_clock_postinit(void) { }
@ -21,6 +23,8 @@ static inline void sched_clock_register(u64 (*read)(void), int bits,
{
;
}
static inline int sched_clock_suspend(void) { return 0; }
static inline void sched_clock_resume(void) { }
#endif
#endif

View File

@ -278,7 +278,7 @@ static u64 notrace suspended_sched_clock_read(void)
return cd.read_data[seq & 1].epoch_cyc;
}
static int sched_clock_suspend(void)
int sched_clock_suspend(void)
{
struct clock_read_data *rd = &cd.read_data[0];
@ -294,7 +294,7 @@ static int sched_clock_suspend(void)
return 0;
}
static void sched_clock_resume(void)
void sched_clock_resume(void)
{
struct clock_read_data *rd = &cd.read_data[0];

View File

@ -18,6 +18,7 @@
#include <linux/percpu.h>
#include <linux/profile.h>
#include <linux/sched.h>
#include <linux/sched_clock.h>
#include <linux/module.h>
#include <trace/events/power.h>
@ -490,6 +491,7 @@ void tick_freeze(void)
if (tick_freeze_depth == num_online_cpus()) {
trace_suspend_resume(TPS("timekeeping_freeze"),
smp_processor_id(), true);
sched_clock_suspend();
timekeeping_suspend();
} else {
tick_suspend_local();
@ -513,6 +515,7 @@ void tick_unfreeze(void)
if (tick_freeze_depth == num_online_cpus()) {
timekeeping_resume();
sched_clock_resume();
trace_suspend_resume(TPS("timekeeping_freeze"),
smp_processor_id(), false);
} else {