From: john stultz <johnstul@us.ibm.com>
To: akpm@osdl.org
Cc: lkml <linux-kernel@vger.kernel.org>, Ingo Molnar <mingo@elte.hu>,
George Anzinger <george@mvista.com>,
Roman Zippel <zippel@linux-m68k.org>,
Ulrich Windl <ulrich.windl@rz.uni-regensburg.de>,
Thomas Gleixner <tglx@linutronix.de>,
Steven Rostedt <rostedt@goodmis.org>,
john stultz <johnstul@us.ibm.com>
Subject: [PATCH 1/10] Time: Reduced NTP rework (part 1)
Date: Thu, 5 Jan 2006 19:13:35 -0700 [thread overview]
Message-ID: <20060106021335.6714.82434.sendpatchset@cog.beaverton.ibm.com> (raw)
In-Reply-To: <20060106021328.6714.45831.sendpatchset@cog.beaverton.ibm.com>
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 | 123 ++++++++++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 85 insertions(+), 38 deletions(-)
linux-2.6.15-rc5_timeofday-ntp-part1_B15.patch
============================================
diff --git a/kernel/timer.c b/kernel/timer.c
index 91572cf..2a0a549 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -589,6 +589,7 @@ 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 */
/*
* this routine handles the overflow of the microsecond field
@@ -716,45 +717,86 @@ static void second_overflow(void)
#endif
}
-/* 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;
- if ((time_adjust_step = time_adjust) != 0 ) {
- /*
- * 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
- */
- time_adjust_step = min(time_adjust_step, (long)tickadj);
- time_adjust_step = max(time_adjust_step, (long)-tickadj);
+ /* increment the interval sum: */
+ interval_sum += interval_ns;
+
+ /* 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.
+ *
+ * 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:
+ */
+ 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;
- }
- 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;
+ /* Reduce by this step the amount of time left: */
+ time_adjust -= time_adjust_step;
+ }
+ 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++;
}
/*
@@ -762,19 +804,24 @@ static void update_wall_time_one_tick(vo
* 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 precomputed NTP
+ * adjustments:
+ * tick_nsec, time_adjust_step, time_adj
+ */
+ long delta_nsec = tick_nsec + time_adjust_step * 1000;
+ delta_nsec += phase_advance();
+
+ xtime_advance(delta_nsec);
+ ntp_advance(tick_nsec);
+ time_interpolator_update(delta_nsec);
+
+ } while (--ticks);
}
/*
next prev parent reply other threads:[~2006-01-06 2:13 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-01-06 2:13 [PATCH 0/10] Time: Generic Timeofday Subsystem (v B15-mm) john stultz
2006-01-06 2:13 ` john stultz [this message]
2006-01-06 2:13 ` [PATCH 2/10] Time: Reduced NTP Rework (part 2) john stultz
2006-01-06 2:13 ` [PATCH 3/10] Time: Clocksource Infrastructure john stultz
2006-01-06 2:13 ` [PATCH 4/10] Time: Generic Timekeeping Infrastructure john stultz
2006-01-06 2:14 ` [PATCH 5/10] Time: i386 Conversion - part 1: Move timer_pit.c to i8253.c john stultz
2006-01-06 2:14 ` [PATCH 6/10] Time: i386 Conversion - part 2: Rework TSC Support john stultz
2006-01-06 2:14 ` [PATCH 7/10] Time: i386 Conversion - part 3: Enable Generic Timekeeping john stultz
2006-01-06 2:14 ` [PATCH 8/10] Time: i386 Conversion - part 4: Remove Old timer_opts Code john stultz
2006-01-06 2:14 ` [PATCH 9/10] Time: i386 Conversion - part 5: ACPI PM variable renaming and config change john stultz
2006-01-06 2:14 ` [PATCH 10/10] Time: i386 Clocksource Drivers john stultz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060106021335.6714.82434.sendpatchset@cog.beaverton.ibm.com \
--to=johnstul@us.ibm.com \
--cc=akpm@osdl.org \
--cc=george@mvista.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
--cc=ulrich.windl@rz.uni-regensburg.de \
--cc=zippel@linux-m68k.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox