Re: [PATCH 1/13] Time: Reduced NTP rework (part 1)
From: Ingo Molnar
Date: Sat Nov 26 2005 - 09:52:48 EST
- clean up the impact of timeofday-ntp-part1.patch
Signed-off-by: Ingo Molnar <mingo@xxxxxxx>
kernel/timer.c | 138 ++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 83 insertions(+), 55 deletions(-)
Index: linux/kernel/timer.c
===================================================================
--- linux.orig/kernel/timer.c
+++ linux/kernel/timer.c
@@ -623,9 +623,9 @@ static long time_adj; /* tick adjust (
long time_reftime; /* time at last adjustment (s) */
long time_adjust;
long time_next_adjust;
-long time_adjust_step; /* per tick time_adjust step */
+long time_adjust_step; /* per tick time_adjust step */
-long total_sppm; /* shifted ppm sum of all NTP adjustments */
+long total_sppm; /* shifted ppm sum of all adjustments */
long offset_adj_ppm;
long tick_adj_ppm;
long singleshot_adj_ppm;
@@ -848,8 +848,7 @@ static void second_overflow(void)
/**
- * ntp_get_ppm_adjustment - Returns Shifted PPM adjustment
- *
+ * ntp_get_ppm_adjustment - return shifted PPM adjustment
*/
long ntp_get_ppm_adjustment(void)
{
@@ -857,41 +856,45 @@ long ntp_get_ppm_adjustment(void)
}
/**
- * ntp_advance() - increments the NTP state machine
- *
+ * ntp_advance - increments the NTP state machine
+ * @interval_ns: interval, in nanoseconds
*/
void ntp_advance(unsigned long interval_ns)
{
static unsigned long interval_sum;
+
unsigned long flags;
+
write_seqlock_irqsave(&ntp_lock, flags);
- /* increment the interval sum */
+ /* increment the interval sum: */
interval_sum += interval_ns;
- /* calculate the per tick singleshot adjtime adjustment step */
+ /* calculate the per tick singleshot adjtime adjustment step: */
while (interval_ns >= tick_nsec) {
time_adjust_step = time_adjust;
if (time_adjust_step) {
- /* We are doing an adjtime thing.
- *
+ /*
+ * We are doing an adjtime thing.
+ *
* Prepare time_adjust_step to be within bounds.
* Note that a positive time_adjust means we want
* the clock to run faster.
*
- * Limit the amount of the step to be in the range
- * -tickadj .. +tickadj
+ * Limit the amount of the step to be in the range
+ * -tickadj .. +tickadj:
*/
- time_adjust_step = min(time_adjust_step, (long)tickadj);
+ time_adjust_step = min(time_adjust_step, (long)tickadj);
time_adjust_step = max(time_adjust_step,
(long)-tickadj);
- /* Reduce by this step the amount of time left */
- time_adjust -= time_adjust_step;
+ /* Reduce by this step the amount of time left: */
+ time_adjust -= time_adjust_step;
}
interval_ns -= tick_nsec;
}
- singleshot_adj_ppm = time_adjust_step*(1000000/HZ); /* usec/tick => ppm */
+ /* usec/tick => ppm: */
+ singleshot_adj_ppm = time_adjust_step*(1000000/HZ);
/* Changes by adjtime() do not take effect till next tick. */
if (time_next_adjust != 0) {
@@ -904,71 +907,96 @@ void ntp_advance(unsigned long interval_
second_overflow();
}
- /* calculate the total continuous ppm adjustment */
+ /* calculate the total continuous ppm adjustment: */
total_sppm = time_freq; /* already shifted by SHIFT_USEC */
total_sppm += offset_adj_ppm << SHIFT_USEC;
total_sppm += tick_adj_ppm << SHIFT_USEC;
total_sppm += singleshot_adj_ppm << SHIFT_USEC;
write_sequnlock_irqrestore(&ntp_lock, flags);
+}
+
+#ifdef CONFIG_GENERIC_TIME
+# define update_wall_time(x) do { } while (0)
+#else
+
+/**
+ * phase_advance - advance the phase
+ * @time_adj: adjustment in nsecs
+ *
+ * advance the phase, once it gets to one microsecond advance the tick more.
+ */
+static inline long phase_advance(long time_adj)
+{
+ long delta = 0;
+
+ time_phase += time_adj;
+
+ if ((time_phase >= FINENSEC) || (time_phase <= -FINENSEC)) {
+ delta = shift_right(time_phase, (SHIFT_SCALE - 10));
+ time_phase -= delta << (SHIFT_SCALE - 10);
+ }
+
+ return delta;
+}
+
+/**
+ * xtime_advance - advance xtime
+ * @delta_nsec: adjustment in nsecs
+ */
+static inline void xtime_advance(long delta_nsec)
+{
+ int leapsecond;
+
+ xtime.tv_nsec += delta_nsec;
+ if (likely(xtime.tv_nsec < NSEC_PER_SEC))
+ return;
+ xtime.tv_nsec -= NSEC_PER_SEC;
+ xtime.tv_sec++;
+
+ /* process leapsecond: */
+ leapsecond = ntp_leapsecond(xtime);
+ if (likely(!leapsecond))
+ return;
+
+ xtime.tv_sec += leapsecond;
+ wall_to_monotonic.tv_sec -= leapsecond;
+ /*
+ * Use of time interpolator for a gradual
+ * change of time:
+ */
+ time_interpolator_update(leapsecond*NSEC_PER_SEC);
+ clock_was_set();
}
-#ifndef CONFIG_GENERIC_TIME
/*
* Using a loop looks inefficient, but "ticks" is
* usually just one (we shouldn't be losing ticks,
* we're doing this this way mainly for interrupt
* latency reasons, not because we think we'll
- * have lots of lost timer ticks
+ * have lots of lost timer ticks)
*/
static void update_wall_time(unsigned long ticks)
{
- long delta_nsec;
- static long time_phase; /* phase offset (scaled us) */
+ static long time_phase; /* phase offset (scaled us) */
do {
- ticks--;
-
- /* Calculate the nsec delta using the
- * precomputed NTP adjustments:
- * tick_nsec, time_adjust_step, time_adj
- */
- delta_nsec = tick_nsec + time_adjust_step * 1000;
/*
- * Advance the phase, once it gets to one microsecond, then
- * advance the tick more.
+ * Calculate the nsec delta using the precomputed NTP
+ * adjustments:
+ * tick_nsec, time_adjust_step, time_adj
*/
- time_phase += time_adj;
- if ((time_phase >= FINENSEC) || (time_phase <= -FINENSEC)) {
- long ltemp = shift_right(time_phase,
- (SHIFT_SCALE - 10));
- time_phase -= ltemp << (SHIFT_SCALE - 10);
- delta_nsec += ltemp;
- }
+ long delta_nsec = tick_nsec + time_adjust_step * 1000;
- xtime.tv_nsec += delta_nsec;
- if (xtime.tv_nsec >= NSEC_PER_SEC) {
- int leapsecond;
- xtime.tv_nsec -= NSEC_PER_SEC;
- xtime.tv_sec++;
- /* process leapsecond */
- leapsecond = ntp_leapsecond(xtime);
- if (leapsecond) {
- xtime.tv_sec += leapsecond;
- wall_to_monotonic.tv_sec -= leapsecond;
- /* Use of time interpolator for a gradual change of time */
- time_interpolator_update(leapsecond*NSEC_PER_SEC);
- clock_was_set();
- }
- }
+ delta_nsec += phase_advance();
+
+ xtime_advance(delta_nsec);
ntp_advance(tick_nsec);
time_interpolator_update(delta_nsec);
- } while (ticks);
+ } while (--ticks);
}
-#else /* !CONFIG_GENERIC_TIME */
-#define update_wall_time(x)
#endif /* !CONFIG_GENERIC_TIME */
/*
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/