time: Avoid scary backtraces when warning of > 11% adj
[pandora-kernel.git] / kernel / time / timekeeping.c
index 06f40ae..16a175b 100644 (file)
@@ -172,21 +172,18 @@ static inline s64 timekeeping_get_ns_raw(void)
        return clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift);
 }
 
-void timekeeping_leap_insert(int leapsecond)
+/* must hold write on timekeeper.lock */
+static void timekeeping_update(bool clearntp)
 {
-       unsigned long flags;
-
-       write_seqlock_irqsave(&timekeeper.lock, flags);
-
-       timekeeper.xtime.tv_sec += leapsecond;
-       timekeeper.wall_to_monotonic.tv_sec -= leapsecond;
+       if (clearntp) {
+               timekeeper.ntp_error = 0;
+               ntp_clear();
+       }
        update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic,
                         timekeeper.clock, timekeeper.mult);
-
-       write_sequnlock_irqrestore(&timekeeper.lock, flags);
-
 }
 
+
 /**
  * timekeeping_forward_now - update clock to the current time
  *
@@ -386,12 +383,7 @@ int do_settimeofday(const struct timespec *tv)
                        timespec_sub(timekeeper.wall_to_monotonic, ts_delta);
 
        timekeeper.xtime = *tv;
-
-       timekeeper.ntp_error = 0;
-       ntp_clear();
-
-       update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic,
-                       timekeeper.clock, timekeeper.mult);
+       timekeeping_update(true);
 
        write_sequnlock_irqrestore(&timekeeper.lock, flags);
 
@@ -425,11 +417,7 @@ int timekeeping_inject_offset(struct timespec *ts)
        timekeeper.wall_to_monotonic =
                                timespec_sub(timekeeper.wall_to_monotonic, *ts);
 
-       timekeeper.ntp_error = 0;
-       ntp_clear();
-
-       update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic,
-                       timekeeper.clock, timekeeper.mult);
+       timekeeping_update(true);
 
        write_sequnlock_irqrestore(&timekeeper.lock, flags);
 
@@ -448,9 +436,12 @@ EXPORT_SYMBOL(timekeeping_inject_offset);
 static int change_clocksource(void *data)
 {
        struct clocksource *new, *old;
+       unsigned long flags;
 
        new = (struct clocksource *) data;
 
+       write_seqlock_irqsave(&timekeeper.lock, flags);
+
        timekeeping_forward_now();
        if (!new->enable || new->enable(new) == 0) {
                old = timekeeper.clock;
@@ -458,6 +449,10 @@ static int change_clocksource(void *data)
                if (old->disable)
                        old->disable(old);
        }
+       timekeeping_update(true);
+
+       write_sequnlock_irqrestore(&timekeeper.lock, flags);
+
        return 0;
 }
 
@@ -668,10 +663,7 @@ void timekeeping_inject_sleeptime(struct timespec *delta)
 
        __timekeeping_inject_sleeptime(delta);
 
-       timekeeper.ntp_error = 0;
-       ntp_clear();
-       update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic,
-                       timekeeper.clock, timekeeper.mult);
+       timekeeping_update(true);
 
        write_sequnlock_irqrestore(&timekeeper.lock, flags);
 
@@ -877,13 +869,15 @@ static void timekeeping_adjust(s64 offset)
        } else /* No adjustment needed */
                return;
 
-       WARN_ONCE(timekeeper.clock->maxadj &&
-                       (timekeeper.mult + adj > timekeeper.clock->mult +
-                                               timekeeper.clock->maxadj),
-                       "Adjusting %s more then 11%% (%ld vs %ld)\n",
+       if (unlikely(timekeeper.clock->maxadj &&
+                       (timekeeper.mult + adj >
+                       timekeeper.clock->mult + timekeeper.clock->maxadj))) {
+               printk_once(KERN_WARNING
+                       "Adjusting %s more than 11%% (%ld vs %ld)\n",
                        timekeeper.clock->name, (long)timekeeper.mult + adj,
                        (long)timekeeper.clock->mult +
                                timekeeper.clock->maxadj);
+       }
        /*
         * So the following can be confusing.
         *
@@ -965,9 +959,11 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift)
 
        timekeeper.xtime_nsec += timekeeper.xtime_interval << shift;
        while (timekeeper.xtime_nsec >= nsecps) {
+               int leap;
                timekeeper.xtime_nsec -= nsecps;
                timekeeper.xtime.tv_sec++;
-               second_overflow();
+               leap = second_overflow(timekeeper.xtime.tv_sec);
+               timekeeper.xtime.tv_sec += leap;
        }
 
        /* Accumulate raw time */
@@ -1078,14 +1074,14 @@ static void update_wall_time(void)
         * xtime.tv_nsec isn't larger then NSEC_PER_SEC
         */
        if (unlikely(timekeeper.xtime.tv_nsec >= NSEC_PER_SEC)) {
+               int leap;
                timekeeper.xtime.tv_nsec -= NSEC_PER_SEC;
                timekeeper.xtime.tv_sec++;
-               second_overflow();
+               leap = second_overflow(timekeeper.xtime.tv_sec);
+               timekeeper.xtime.tv_sec += leap;
        }
 
-       /* check to see if there is a new clocksource to use */
-       update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic,
-                       timekeeper.clock, timekeeper.mult);
+       timekeeping_update(false);
 
 out:
        write_sequnlock_irqrestore(&timekeeper.lock, flags);