summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorSteve Muckle <smuckle@codeaurora.org>2014-11-13 18:06:59 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:01:06 -0700
commit6370716bc33928f91d75ecb5173986c79dedb111 (patch)
tree4b0f696a614e47259e17791395bbf71df5b395d0 /kernel
parent57ee8ef06eb2ac56c9c227e687e9df8d02bd691e (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.c3
-rw-r--r--kernel/time/sched_clock.c8
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;
}
/*