linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/9] Time: Reduced NTP rework (part 1)
@ 2006-03-04  4:44 john stultz
  2006-03-04  4:44 ` [PATCH 2/9] Time: Reduced NTP Rework (part 2) john stultz
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: john stultz @ 2006-03-04  4:44 UTC (permalink / raw)
  To: lkml; +Cc: john stultz

	This reworks some of the interrupt time NTP adjustments so that 
it could be re-used by the generic timekeeping infrastructure. 
	
This is done by logically separating the code which adjusts xtime from 
the code that decides, based on the NTP state variables, how much to 
adjust time each tick.
	
This should not affect the existing behavior, but just separate the 
logical functionality so it can be re-used.

thanks
-john

Signed-off-by: John Stultz <johnstul@us.ibm.com>

 timer.c |   95 +++++++++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 67 insertions(+), 28 deletions(-)

linux-2.6.16-rc5_timeofday-ntp-part1_B20.patch
============================================
diff --git a/kernel/timer.c b/kernel/timer.c
index fc6646f..680fa7e 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -741,34 +741,68 @@ static long adjtime_adjustment(void)
 	return time_adjust_step;
 }
 
-/* in the NTP reference this is called "hardclock()" */
-static void update_wall_time_one_tick(void)
+/**
+ * ntp_advance - increments the NTP state machine
+ * @interval_ns: interval, in nanoseconds
+ *
+ * Must be holding the xtime writelock when calling.
+ */
+static void ntp_advance(unsigned long interval_ns)
 {
-	long time_adjust_step, delta_nsec;
+	static unsigned long interval_sum;
 
-	time_adjust_step = adjtime_adjustment();
-	if (time_adjust_step)
-		/* Reduce by this step the amount of time left  */
-		time_adjust -= time_adjust_step;
-	delta_nsec = tick_nsec + time_adjust_step * 1000;
-	/*
-	 * Advance the phase, once it gets to one microsecond, then
-	 * advance the tick more.
-	 */
-	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;
+	/* increment the interval sum: */
+	interval_sum += interval_ns;
+
+	/* calculate the per tick singleshot adjtime adjustment step: */
+	while (interval_ns >= tick_nsec) {
+		time_adjust -= adjtime_adjustment();
+		interval_ns -= tick_nsec;
 	}
-	xtime.tv_nsec += delta_nsec;
-	time_interpolator_update(delta_nsec);
 
 	/* Changes by adjtime() do not take effect till next tick. */
 	if (time_next_adjust != 0) {
 		time_adjust = time_next_adjust;
 		time_next_adjust = 0;
 	}
+
+	while (interval_sum >= NSEC_PER_SEC) {
+		interval_sum -= NSEC_PER_SEC;
+		second_overflow();
+	}
+}
+
+/**
+ * phase_advance - advance the phase
+ *
+ * advance the phase, once it gets to one nanosecond advance the tick more.
+ */
+static inline long phase_advance(void)
+{
+	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)
+{
+	xtime.tv_nsec += delta_nsec;
+	if (likely(xtime.tv_nsec < NSEC_PER_SEC))
+		return;
+
+	xtime.tv_nsec -= NSEC_PER_SEC;
+	xtime.tv_sec++;
 }
 
 /*
@@ -792,19 +826,24 @@ u64 current_tick_length(void)
  * 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)
 {
 	do {
-		ticks--;
-		update_wall_time_one_tick();
-		if (xtime.tv_nsec >= 1000000000) {
-			xtime.tv_nsec -= 1000000000;
-			xtime.tv_sec++;
-			second_overflow();
-		}
-	} while (ticks);
+		/*
+		 * Calculate the nsec delta using the NTP
+		 * adjustments:
+		 *     tick_nsec, adjtime_adjustment(), phase_advance()
+		 */
+		long delta_nsec = tick_nsec + adjtime_adjustment() * 1000;
+		delta_nsec += phase_advance();
+
+		xtime_advance(delta_nsec);
+		ntp_advance(tick_nsec);
+		time_interpolator_update(delta_nsec);
+
+	} while (--ticks);
 }
 
 /*

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2006-03-04  4:46 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-04  4:44 [PATCH 1/9] Time: Reduced NTP rework (part 1) john stultz
2006-03-04  4:44 ` [PATCH 2/9] Time: Reduced NTP Rework (part 2) john stultz
2006-03-04  4:44 ` [PATCH 3/9] Time: Clocksource Infrastructure john stultz
2006-03-04  4:44 ` [PATCH 4/9] Time: Generic Timekeeping Infrastructure john stultz
2006-03-04  4:44 ` [PATCH 5/9] Time: i386 Conversion - part 1: Move timer_pit.c to i8253.c john stultz
2006-03-04  4:44 ` [PATCH 6/9] Time: i386 Conversion - part 2: Rework TSC Support john stultz
2006-03-04  4:44 ` [PATCH 7/9] Time: i386 Conversion - part 3: Enable Generic Timekeeping john stultz
2006-03-04  4:44 ` [PATCH 8/9] Time: i386 Conversion - part 4: Remove Old timer_opts Code john stultz
2006-03-04  4:44 ` [PATCH 9/9] Time: i386 Clocksource Drivers john stultz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).