sched: fix sched_clock_cpu()
authorPeter Zijlstra <a.p.zijlstra@chello.nl>
Thu, 29 May 2008 08:07:15 +0000 (10:07 +0200)
committerIngo Molnar <mingo@elte.hu>
Thu, 29 May 2008 09:29:19 +0000 (11:29 +0200)
Make sched_clock_cpu() return 0 before it has been initialized and avoid
corrupting its state due to doing so.

This fixes the weird printk timestamp jump reported.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
kernel/sched_clock.c

index 9c597e37f7de66b598db43fda9beebcb1b752ef0..ce05271219abcc5bf7dd4087d91ce98f487ee2e9 100644 (file)
@@ -59,22 +59,26 @@ static inline struct sched_clock_data *cpu_sdc(int cpu)
        return &per_cpu(sched_clock_data, cpu);
 }
 
+static __read_mostly int sched_clock_running;
+
 void sched_clock_init(void)
 {
        u64 ktime_now = ktime_to_ns(ktime_get());
-       u64 now = 0;
+       unsigned long now_jiffies = jiffies;
        int cpu;
 
        for_each_possible_cpu(cpu) {
                struct sched_clock_data *scd = cpu_sdc(cpu);
 
                scd->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
-               scd->prev_jiffies = jiffies;
-               scd->prev_raw = now;
-               scd->tick_raw = now;
+               scd->prev_jiffies = now_jiffies;
+               scd->prev_raw = 0;
+               scd->tick_raw = 0;
                scd->tick_gtod = ktime_now;
                scd->clock = ktime_now;
        }
+
+       sched_clock_running = 1;
 }
 
 /*
@@ -136,6 +140,9 @@ u64 sched_clock_cpu(int cpu)
        struct sched_clock_data *scd = cpu_sdc(cpu);
        u64 now, clock;
 
+       if (unlikely(!sched_clock_running))
+               return 0ull;
+
        WARN_ON_ONCE(!irqs_disabled());
        now = sched_clock();
 
@@ -174,6 +181,9 @@ void sched_clock_tick(void)
        struct sched_clock_data *scd = this_scd();
        u64 now, now_gtod;
 
+       if (unlikely(!sched_clock_running))
+               return;
+
        WARN_ON_ONCE(!irqs_disabled());
 
        now = sched_clock();