[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ntp-bugs
Subject:    [ntp:bugs] ntp and linux
From:       Harald Hoyer <harald () redhat ! de>
Date:       2003-02-17 14:48:20
[Download RAW message or body]

For me, the time slewing (-x) on Linux only works with the two attached 
patches.
The first one clamps the parameters for ntp_adjtime, the second changes 
the algorithm a little bit.
Seems that using the current_offset was taking the value of the last 
ntp_adjtime() call, which could be > 900 seconds old.
Also, if we speedup regulation with ntp_adjtime() by making 
clock_minstep smaller, we reach the -0.128...0.128 range faster and do 
not oscillate over it.

Comments? Questions?

All I can say: It workx for me and keeps my time very accurate without 
stepping :)))

-- 
Harald Hoyer, Software Developer   Tel. : +49-711-96437-0
Red Hat GmbH                       Fax. : +49-711-96437-111
Hauptstaetterstr. 58               Email: Harald.Hoyer@redhat.de
D-70178 Stuttgart                  Web  : http://www.redhat.de/


["ntp-4.1.73-limit.patch" (text/plain)]

diff -ur ntp-4.1.73/ntpd/ntp_loopfilter.c ntp-4.1.73-2/ntpd/ntp_loopfilter.c
--- ntp-4.1.73/ntpd/ntp_loopfilter.c	2003-01-20 02:38:10.000000000 +0100
+++ ntp-4.1.73-2/ntpd/ntp_loopfilter.c	2003-01-29 14:25:11.000000000 +0100
@@ -128,6 +128,8 @@
 int	pll_nano;		/* nanosecond kernel switch */
 #endif /* KERNEL_PLL */
 
+static void limit_ntp_adjtime(struct timex *);
+
 /*
  * Clock state machine control flags
  */
@@ -573,13 +575,18 @@
 		 * the pigs. In any case, fetch the kernel offset and
 		 * frequency and pretend we did it here.
 		 */
-		if (ntp_adjtime(&ntv) == TIME_ERROR) {
-			if (ntv.status != pll_status)
-				msyslog(LOG_ERR,
-				    "kernel time discipline status change %x",
-				    ntv.status);
-			ntv.status &= ~(STA_PPSFREQ | STA_PPSTIME);
-		}
+		limit_ntp_adjtime(&ntv);
+		if (ntp_adjtime(&ntv) != 0) {
+		  if (debug > 2)
+		    msyslog(LOG_ERR, "ntp_adjtime() == TIME_ERROR "
+			    "offset = %ld", ntv.offset);
+		  
+		  ntv.status &= ~(STA_PPSFREQ | STA_PPSTIME); 
+		} 
+		if (ntv.status != pll_status)
+		  msyslog(LOG_ERR,
+			  "kernel time discipline status change %x",
+			  ntv.status);
 		pll_status = ntv.status;
 		if (pll_nano)
 			clock_offset = ntv.offset / 1e9;
@@ -840,8 +848,13 @@
 			    "sigaction() fails to save SIGSYS trap: %m");
 			pll_control = 0;
 		}
-		if (sigsetjmp(env, 1) == 0)
-			ntp_adjtime(&ntv);
+		if (sigsetjmp(env, 1) == 0) {
+		  limit_ntp_adjtime(&ntv);
+		  if(ntp_adjtime(&ntv) == TIME_ERROR)
+		    if (debug > 2)
+		      msyslog(LOG_ERR, "ntp_adjtime() == TIME_ERROR "
+			      "offset = %ld", ntv.offset);
+		}
 		if ((sigaction(SIGSYS, &sigsys,
 		    (struct sigaction *)NULL))) {
 			msyslog(LOG_ERR,
@@ -849,7 +862,12 @@
 			pll_control = 0;
 		}
 #else /* SIGSYS */
-		ntp_adjtime(&ntv);
+		limit_ntp_adjtime(&ntv);
+		if (ntp_adjtime(&ntv) == TIME_ERROR)
+		  if (debug > 2)
+		    msyslog(LOG_ERR, "ntp_adjtime() == TIME_ERROR "
+			    "offset = %ld", ntv.offset);
+
 #endif /* SIGSYS */
 		pll_status = ntv.status;
 		if (pll_control) {
@@ -899,7 +917,12 @@
 				ntv.freq = (int32)(drift_comp *
 				    65536e6);
 			}
-			(void)ntp_adjtime(&ntv);
+			limit_ntp_adjtime(&ntv);
+			if(ntp_adjtime(&ntv) == TIME_ERROR)
+			  if (debug > 2)
+			    msyslog(LOG_ERR, "ntp_adjtime() == TIME_ERROR "
+				    "offset = %ld", ntv.offset);
+
 		}
 #endif /* KERNEL_PLL */
 		break;
@@ -959,3 +982,28 @@
 	siglongjmp(env, 1);
 }
 #endif /* KERNEL_PLL && SIGSYS */
+
+#ifdef KERNEL_PLL
+
+static void limit_ntp_adjtime(struct timex *tmx)
+{
+#include <linux/timex.h>
+#define NEW_MAXTC 10
+  if (tmx->freq >= MAXFREQ)
+    tmx->freq = MAXFREQ-1;
+  else if (tmx->freq <= -MAXFREQ)
+    tmx->freq = -MAXFREQ+1;
+  
+  if (tmx->maxerror < 0)
+    tmx->maxerror = 0;
+  else if (tmx->maxerror >= NTP_PHASE_LIMIT)
+    tmx->maxerror = NTP_PHASE_LIMIT-1;
+  if (tmx->constant >= NEW_MAXTC)
+    tmx->constant = NEW_MAXTC-1;
+  
+  if (tmx->offset <= - MAXPHASE)
+    tmx->offset = -MAXPHASE+1;
+  else if (tmx->offset >= MAXPHASE )
+    tmx->offset = MAXPHASE-1;  
+}
+#endif
diff -ur ntp-4.1.73/ntpd/ntp_proto.c ntp-4.1.73-2/ntpd/ntp_proto.c
--- ntp-4.1.73/ntpd/ntp_proto.c	2003-01-18 01:34:42.000000000 +0100
+++ ntp-4.1.73-2/ntpd/ntp_proto.c	2003-01-27 22:08:04.000000000 +0100
@@ -2179,7 +2180,7 @@
 			printf("select: pps offset %.6f\n",
 			    sys_offset);
 #endif
-	} else {
+	} else if (nlist) {
 		if (typesystem)
 			sys_peer = osys_peer;
 		else

["ntp-4.1.1c-loopfilter.patch" (text/plain)]

--- ntp-4.1.1c-rc1/ntpd/ntp_loopfilter.c.loop	2003-02-13 17:14:19.000000000 +0100
+++ ntp-4.1.1c-rc1/ntpd/ntp_loopfilter.c	2003-02-13 17:44:43.000000000 +0100
@@ -340,6 +340,22 @@
 	 * never occur. See the instruction manual for the details how
 	 * these actions interact with the command line options.
 	 */
+
+#if defined(KERNEL_PLL)
+	  /*
+	   * Get the current clock_offset from the kernel
+	   * or we would calc with an old value from
+	   * our last update
+	   */
+	  memset((char *)&ntv, 0, sizeof(ntv));
+	  if (ntp_adjtime(&ntv) == 0) {
+	    if (pll_nano)
+	      clock_offset = ntv.offset / 1e9;
+	    else
+	      clock_offset = ntv.offset / 1e6;
+	  }
+#endif
+
 	retval = 0;
 	if (sys_poll > peer->maxpoll)
 		sys_poll = peer->maxpoll;
@@ -689,6 +705,18 @@
 		}
 	}
 
+	if (!allow_step) {
+	  /*
+	   * If we cannot step, we have to be faster, otherwise we
+	   * would miss the -CLOCK_MAX...CLOCK_MAX range.
+	   */
+	  clock_minstep = 1 << (2 + sys_poll);
+	  clock_minstep = (clock_minstep > CLOCK_MINSTEP) ? CLOCK_MINSTEP
+	    : clock_minstep;
+	  if (debug)
+	    printf("clock_minstep %f s\n", clock_minstep);
+	}
+
 	/*
 	 * Update the system time variables.
 	 */



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic