|
@@ -202,7 +202,25 @@ static void __sched_clock_gtod_offset(void)
|
|
|
|
|
|
void __init sched_clock_init(void)
|
|
|
{
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set __gtod_offset such that once we mark sched_clock_running,
|
|
|
+ * sched_clock_tick() continues where sched_clock() left off.
|
|
|
+ *
|
|
|
+ * Even if TSC is buggered, we're still UP at this point so it
|
|
|
+ * can't really be out of sync.
|
|
|
+ */
|
|
|
+ local_irq_save(flags);
|
|
|
+ __sched_clock_gtod_offset();
|
|
|
+ local_irq_restore(flags);
|
|
|
+
|
|
|
sched_clock_running = 1;
|
|
|
+
|
|
|
+ /* Now that sched_clock_running is set adjust scd */
|
|
|
+ local_irq_save(flags);
|
|
|
+ sched_clock_tick();
|
|
|
+ local_irq_restore(flags);
|
|
|
}
|
|
|
/*
|
|
|
* We run this as late_initcall() such that it runs after all built-in drivers,
|
|
@@ -356,7 +374,7 @@ u64 sched_clock_cpu(int cpu)
|
|
|
return sched_clock() + __sched_clock_offset;
|
|
|
|
|
|
if (unlikely(!sched_clock_running))
|
|
|
- return 0ull;
|
|
|
+ return sched_clock();
|
|
|
|
|
|
preempt_disable_notrace();
|
|
|
scd = cpu_sdc(cpu);
|