diff options
author | Steve Muckle <smuckle@codeaurora.org> | 2014-11-13 18:06:59 -0800 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:01:06 -0700 |
commit | 6370716bc33928f91d75ecb5173986c79dedb111 (patch) | |
tree | 4b0f696a614e47259e17791395bbf71df5b395d0 /kernel | |
parent | 57ee8ef06eb2ac56c9c227e687e9df8d02bd691e (diff) |
sched: do not set window until sched_clock is fully initialized
The system initially uses a jiffy-based sched clock. When the platform
registers a new timer for sched_clock, sched_clock can jump backwards.
Once sched_clock_postinit() runs it should be safe to rely on it.
Also sched_clock_cpu() relies on completion of sched_clock_init()
and until that happens sched_clock_cpu() returns zero. This is used
in the irq accounting path which window-based stats relies upon.
So do not set window_start until sched_clock_cpu() is working.
Change-Id: Ided349de8f8554f80a027ace0f63ea52b1c38c68
Signed-off-by: Steve Muckle <smuckle@codeaurora.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched/core.c | 3 | ||||
-rw-r--r-- | kernel/time/sched_clock.c | 8 |
2 files changed, 10 insertions, 1 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index d43925c6e560..59dfded79cad 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1919,7 +1919,8 @@ static inline void set_window_start(struct rq *rq) int cpu = cpu_of(rq); struct rq *sync_rq = cpu_rq(sync_cpu); - if (rq->window_start || !sched_enable_hmp) + if (rq->window_start || !sched_enable_hmp || + !sched_clock_initialized() || !sched_clock_cpu(cpu)) return; if (cpu == sync_cpu) { diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c index a26036d37a38..0637823aa5a6 100644 --- a/kernel/time/sched_clock.c +++ b/kernel/time/sched_clock.c @@ -70,6 +70,7 @@ struct clock_data { static struct hrtimer sched_clock_timer; static int irqtime = -1; +static int initialized; core_param(irqtime, irqtime, int, 0400); @@ -231,6 +232,11 @@ sched_clock_register(u64 (*read)(void), int bits, unsigned long rate) pr_debug("Registered %pF as sched_clock source\n", read); } +int sched_clock_initialized(void) +{ + return initialized; +} + void __init sched_clock_postinit(void) { /* @@ -249,6 +255,8 @@ void __init sched_clock_postinit(void) hrtimer_init(&sched_clock_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); sched_clock_timer.function = sched_clock_poll; hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL); + + initialized = 1; } /* |