]> Pileus Git - ~andy/linux/blobdiff - kernel/time/timekeeping.c
ntp: Fix leap-second hrtimer livelock
[~andy/linux] / kernel / time / timekeeping.c
index b53da5ecbea2e690490ed6395aa47e45bf0bfda0..5d76e09ddd3d04d1748e0ece2970d090c5b2621f 100644 (file)
@@ -184,18 +184,6 @@ static void timekeeping_update(bool clearntp)
 }
 
 
-void timekeeping_leap_insert(int leapsecond)
-{
-       unsigned long flags;
-
-       write_seqlock_irqsave(&timekeeper.lock, flags);
-       timekeeper.xtime.tv_sec += leapsecond;
-       timekeeper.wall_to_monotonic.tv_sec -= leapsecond;
-       timekeeping_update(false);
-       write_sequnlock_irqrestore(&timekeeper.lock, flags);
-
-}
-
 /**
  * timekeeping_forward_now - update clock to the current time
  *
@@ -969,9 +957,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 */
@@ -1082,9 +1072,11 @@ 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;
        }
 
        timekeeping_update(false);