[PATCH 9/10] NTP: convert to the NTP4 model

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This converts the kernel ntp model into a model which matches the
nanokernel reference implementations. The previous patches already
increased the resolution and precision of the computations, so that this
conversion becomes quite simple.



Signed-off-by: Roman Zippel <[email protected]>

---

 include/linux/timex.h |   12 +++++-------
 kernel/time.c         |   40 ++++++++++++++++------------------------
 kernel/timer.c        |   12 ++----------
 3 files changed, 23 insertions(+), 41 deletions(-)

Index: linux-2.6-mm/include/linux/timex.h
===================================================================
--- linux-2.6-mm.orig/include/linux/timex.h	2005-12-21 12:12:22.000000000 +0100
+++ linux-2.6-mm/include/linux/timex.h	2005-12-21 12:12:26.000000000 +0100
@@ -71,10 +71,9 @@
  * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours,
  * respectively.
  */
-#define SHIFT_KG 6		/* phase factor (shift) */
-#define SHIFT_KF 16		/* PLL frequency factor (shift) */
-#define SHIFT_KH 2		/* FLL frequency factor (shift) */
-#define MAXTC 6			/* maximum time constant (shift) */
+#define SHIFT_PLL	4	/* PLL frequency factor (shift) */
+#define SHIFT_FLL	2	/* FLL frequency factor (shift) */
+#define MAXTC		10	/* maximum time constant (shift) */
 
 /*
  * The SHIFT_SCALE define establishes the decimal point of the time_phase
@@ -91,7 +90,6 @@
  * FINENSEC is 1 ns in SHIFT_UPDATE units of the time_phase variable.
  */
 #define SHIFT_SCALE 22		/* phase scale (shift) */
-#define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* time offset scale (shift) */
 #define SHIFT_USEC 16		/* frequency offset scale (shift) */
 #define SHIFT_NSEC 12		/* kernel frequency offset scale */
 #define FINENSEC (1L << SHIFT_SCALE) /* ~1 ns in phase units */
@@ -99,8 +97,8 @@
 #define MAXPHASE 500000000L	/* max phase error (ns) */
 #define MAXFREQ (500000L << SHIFT_NSEC)		/* max frequency error (ns/s) */
 #define MAXFREQ_USER (500L << SHIFT_USEC)	/* max frequency error (ppm) */
-#define MINSEC 16L              /* min interval between updates (s) */
-#define MAXSEC 1200L            /* max interval between updates (s) */
+#define MINSEC 256		/* min interval between updates (s) */
+#define MAXSEC 2048		/* max interval between updates (s) */
 #define NTP_PHASE_LIMIT	((MAXPHASE / 1000) << 5) /* beyond max. dispersion */
 
 /*
Index: linux-2.6-mm/kernel/time.c
===================================================================
--- linux-2.6-mm.orig/kernel/time.c	2005-12-21 12:12:22.000000000 +0100
+++ linux-2.6-mm/kernel/time.c	2005-12-21 12:12:26.000000000 +0100
@@ -212,7 +212,7 @@ void __attribute__ ((weak)) notify_arch_
 int do_adjtimex(struct timex *txc)
 {
         long ltemp, mtemp, save_adjust;
-	s64 freq_adj;
+	s64 freq_adj, temp64;
 	int result;
 
 	/* In order to modify anything, you gotta be super-user! */
@@ -284,7 +284,7 @@ int do_adjtimex(struct timex *txc)
 		    result = -EINVAL;
 		    goto leave;
 		}
-		time_constant = txc->constant;
+		time_constant = min(txc->constant + 4, (long)MAXTC);
 	    }
 
 	    if (txc->modes & ADJ_OFFSET) {	/* values checked earlier */
@@ -316,28 +316,20 @@ int do_adjtimex(struct timex *txc)
 		        time_reftime = xtime.tv_sec;
 		    mtemp = xtime.tv_sec - time_reftime;
 		    time_reftime = xtime.tv_sec;
-		    freq_adj = 0;
-		    if (time_status & STA_FLL) {
-		        if (mtemp >= MINSEC) {
-			    if (time_offset < 0) {
-				freq_adj = (s64)-time_offset << SHIFT_USEC;
-				do_div(freq_adj, mtemp);
-				freq_adj = -(freq_adj >> SHIFT_KH);
-			    } else {
-				freq_adj = (s64)time_offset << SHIFT_USEC;
-				do_div(freq_adj, mtemp);
-				freq_adj = freq_adj >> SHIFT_KH;
-			    }
-			} else /* calibration interval too short (p. 12) */
-				result = TIME_ERROR;
-		    } else {	/* PLL mode */
-		        if (mtemp < MAXSEC) {
-			    freq_adj = (s64)ltemp * mtemp;
-			    freq_adj = shift_right(freq_adj,(time_constant +
-						       time_constant +
-						       SHIFT_KF - SHIFT_USEC));
-			} else /* calibration interval too long (p. 12) */
-				result = TIME_ERROR;
+
+		    freq_adj = (s64)time_offset * mtemp;
+		    freq_adj = shift_right(freq_adj, (time_constant + SHIFT_PLL +
+						      2) * 2 - SHIFT_NSEC);
+		    if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) {
+			if (time_offset < 0) {
+			    temp64 = (s64)-time_offset << SHIFT_NSEC;
+			    do_div(temp64, mtemp << SHIFT_FLL);
+			    freq_adj -= temp64;
+			} else {
+			    temp64 = (s64)time_offset << SHIFT_NSEC;
+			    do_div(temp64, mtemp << SHIFT_FLL);
+			    freq_adj += temp64;
+			}
 		    }
 		    freq_adj += time_freq;
 		    freq_adj = min(freq_adj, (s64)MAXFREQ);
Index: linux-2.6-mm/kernel/timer.c
===================================================================
--- linux-2.6-mm.orig/kernel/timer.c	2005-12-21 12:12:22.000000000 +0100
+++ linux-2.6-mm/kernel/timer.c	2005-12-21 12:12:26.000000000 +0100
@@ -713,11 +713,7 @@ static void second_overflow(void)
 	 * over not more than the number of seconds between updates.
 	 */
 	if (time_offset < 0) {
-		ltemp = -time_offset;
-		if (!(time_status & STA_FLL))
-			ltemp >>= SHIFT_KG + time_constant;
-		if (ltemp > (((MAXPHASE / HZ) << SHIFT_HZ) / MINSEC))
-			ltemp = ((MAXPHASE / HZ) << SHIFT_HZ) / MINSEC;
+		ltemp = -time_offset >> (SHIFT_PLL + time_constant);
 		time_offset += ltemp;
 		tick_nsec_curr -= ltemp >> SHIFT_HZ;
 		time_adj_curr -= (ltemp << (SHIFT_SCALE - SHIFT_HZ)) & (FINENSEC - 1);
@@ -726,11 +722,7 @@ static void second_overflow(void)
 			time_adj_curr += FINENSEC;
 		}
 	} else {
-		ltemp = time_offset;
-		if (!(time_status & STA_FLL))
-			ltemp >>= SHIFT_KG + time_constant;
-		if (ltemp > (((MAXPHASE / HZ) << SHIFT_HZ) / MINSEC))
-			ltemp = ((MAXPHASE / HZ) << SHIFT_HZ) / MINSEC;
+		ltemp = time_offset >> (SHIFT_PLL + time_constant);
 		time_offset -= ltemp;
 		tick_nsec_curr += ltemp >> SHIFT_HZ;
 		time_adj_curr += (ltemp << (SHIFT_SCALE - SHIFT_HZ)) & (FINENSEC - 1);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux