aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRoman Zippel <zippel@linux-m68k.org>2006-10-01 02:28:22 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:26 -0400
commitb0ee75561beadc4db4d9a899c8ef4a7db50aa0ab (patch)
treee50354c74ce17f6ea78dc1d7fac608788de517f3 /kernel
parent4c7ee8de956fc250fe31e2fa91f6da980fabe317 (diff)
[PATCH] ntp: add ntp_update_frequency
This introduces ntp_update_frequency() and deinlines ntp_clear() (as it's not performance critical). ntp_update_frequency() calculates the base tick length using tick_usec and adds a base adjustment, in case the frequency doesn't divide evenly by HZ. Signed-off-by: Roman Zippel <zippel@linux-m68k.org> Cc: john stultz <johnstul@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time/ntp.c50
-rw-r--r--kernel/timer.c11
2 files changed, 48 insertions, 13 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 8ccce15b4b23..77137bec2aea 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -15,6 +15,13 @@
15#include <asm/div64.h> 15#include <asm/div64.h>
16#include <asm/timex.h> 16#include <asm/timex.h>
17 17
18/*
19 * Timekeeping variables
20 */
21unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */
22unsigned long tick_nsec; /* ACTHZ period (nsec) */
23static u64 tick_length, tick_length_base;
24
18/* Don't completely fail for HZ > 500. */ 25/* Don't completely fail for HZ > 500. */
19int tickadj = 500/HZ ? : 1; /* microsecs */ 26int tickadj = 500/HZ ? : 1; /* microsecs */
20 27
@@ -37,6 +44,36 @@ long time_reftime; /* time at last adjustment (s) */
37long time_adjust; 44long time_adjust;
38long time_next_adjust; 45long time_next_adjust;
39 46
47/**
48 * ntp_clear - Clears the NTP state variables
49 *
50 * Must be called while holding a write on the xtime_lock
51 */
52void ntp_clear(void)
53{
54 time_adjust = 0; /* stop active adjtime() */
55 time_status |= STA_UNSYNC;
56 time_maxerror = NTP_PHASE_LIMIT;
57 time_esterror = NTP_PHASE_LIMIT;
58
59 ntp_update_frequency();
60
61 tick_length = tick_length_base;
62}
63
64#define CLOCK_TICK_OVERFLOW (LATCH * HZ - CLOCK_TICK_RATE)
65#define CLOCK_TICK_ADJUST (((s64)CLOCK_TICK_OVERFLOW * NSEC_PER_SEC) / (s64)CLOCK_TICK_RATE)
66
67void ntp_update_frequency(void)
68{
69 tick_length_base = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << TICK_LENGTH_SHIFT;
70 tick_length_base += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT;
71
72 do_div(tick_length_base, HZ);
73
74 tick_nsec = tick_length_base >> TICK_LENGTH_SHIFT;
75}
76
40/* 77/*
41 * this routine handles the overflow of the microsecond field 78 * this routine handles the overflow of the microsecond field
42 * 79 *
@@ -151,6 +188,7 @@ void second_overflow(void)
151 */ 188 */
152 time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7); 189 time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
153#endif 190#endif
191 tick_length = tick_length_base;
154} 192}
155 193
156/* 194/*
@@ -204,14 +242,13 @@ void update_ntp_one_tick(void)
204 */ 242 */
205u64 current_tick_length(void) 243u64 current_tick_length(void)
206{ 244{
207 long delta_nsec;
208 u64 ret; 245 u64 ret;
209 246
210 /* calculate the finest interval NTP will allow. 247 /* calculate the finest interval NTP will allow.
211 * ie: nanosecond value shifted by (SHIFT_SCALE - 10) 248 * ie: nanosecond value shifted by (SHIFT_SCALE - 10)
212 */ 249 */
213 delta_nsec = tick_nsec + adjtime_adjustment() * 1000; 250 ret = tick_length;
214 ret = (u64)delta_nsec << TICK_LENGTH_SHIFT; 251 ret += (u64)(adjtime_adjustment() * 1000) << TICK_LENGTH_SHIFT;
215 ret += (s64)time_adj << (TICK_LENGTH_SHIFT - (SHIFT_SCALE - 10)); 252 ret += (s64)time_adj << (TICK_LENGTH_SHIFT - (SHIFT_SCALE - 10));
216 253
217 return ret; 254 return ret;
@@ -351,10 +388,11 @@ int do_adjtimex(struct timex *txc)
351 time_freq = max(time_freq, -time_tolerance); 388 time_freq = max(time_freq, -time_tolerance);
352 } /* STA_PLL */ 389 } /* STA_PLL */
353 } /* txc->modes & ADJ_OFFSET */ 390 } /* txc->modes & ADJ_OFFSET */
354 if (txc->modes & ADJ_TICK) { 391 if (txc->modes & ADJ_TICK)
355 tick_usec = txc->tick; 392 tick_usec = txc->tick;
356 tick_nsec = TICK_USEC_TO_NSEC(tick_usec); 393
357 } 394 if (txc->modes & ADJ_TICK)
395 ntp_update_frequency();
358 } /* txc->modes */ 396 } /* txc->modes */
359leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0) 397leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
360 result = TIME_ERROR; 398 result = TIME_ERROR;
diff --git a/kernel/timer.c b/kernel/timer.c
index 5fccc7cbf3b4..78d3fa10fcd6 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -562,12 +562,6 @@ found:
562 562
563/******************************************************************/ 563/******************************************************************/
564 564
565/*
566 * Timekeeping variables
567 */
568unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */
569unsigned long tick_nsec = TICK_NSEC; /* ACTHZ period (nsec) */
570
571/* 565/*
572 * The current time 566 * The current time
573 * wall_to_monotonic is what we need to add to xtime (or xtime corrected 567 * wall_to_monotonic is what we need to add to xtime (or xtime corrected
@@ -757,10 +751,13 @@ void __init timekeeping_init(void)
757 unsigned long flags; 751 unsigned long flags;
758 752
759 write_seqlock_irqsave(&xtime_lock, flags); 753 write_seqlock_irqsave(&xtime_lock, flags);
754
755 ntp_clear();
756
760 clock = clocksource_get_next(); 757 clock = clocksource_get_next();
761 clocksource_calculate_interval(clock, tick_nsec); 758 clocksource_calculate_interval(clock, tick_nsec);
762 clock->cycle_last = clocksource_read(clock); 759 clock->cycle_last = clocksource_read(clock);
763 ntp_clear(); 760
764 write_sequnlock_irqrestore(&xtime_lock, flags); 761 write_sequnlock_irqrestore(&xtime_lock, flags);
765} 762}
766 763