Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Apr 2011 13:32:03 -0600 (MDT)
From:      Ian Lepore <freebsd@damnhippie.dyndns.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/156481: [patch] kernel incorrectly reports PPS jitter with accurate measurements
Message-ID:  <201104181932.p3IJW3HP059660@revolution.hippie.lan>
Resent-Message-ID: <201104181950.p3IJo5Jc025668@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         156481
>Category:       kern
>Synopsis:       [patch] kernel incorrectly reports PPS jitter with accurate measurements
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 18 19:50:04 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Ian Lepore <freebsd@damnhippie.dyndns.org>
>Release:        FreeBSD 8.2-RC3 arm
>Organization:
none
>Environment:
FreeBSD dvb 8.2-RC3 FreeBSD 8.2-RC3 #49: Tue Feb 15 22:52:14 UTC 2011     root@revolution.hippie.lan:/usr/obj/arm/usr/src/sys/DVB  arm

>Description:

The kernel maintains an acceptable-jitter threshold based on a running 
average of the measurement magnitude.  After receiving a series of small 
delta measurements the jitter threshold is reduced to less than the 
measurement resolution, so that when a measurement crosses a timer tick 
boundary and pops a resolution-sized delta it gets flagged as jitter.  

On one of our systems that uses a timecounter running at ~2.8 mhz (so the 
measurement resolution is approximately 357 nanoseconds), a printf was 
added to the code that checks for pps jitter and the data it logged 
confirms the problem: 

Apr 13 10:57:49 kernel: u_nsec 351 popcorn threshold 32 is 4*pps_jitter 8)
Apr 13 10:59:13 kernel: u_nsec 352 popcorn threshold 24 is 4*pps_jitter 6)
Apr 13 11:00:51 kernel: u_nsec 352 popcorn threshold 20 is 4*pps_jitter 5)
Apr 13 11:03:01 kernel: u_nsec 354 popcorn threshold 8 is 4*pps_jitter 2)

In the pathological worst case the jitter threshold can get reduced to 
zero and any non-zero measurement is flagged as jitter:

Apr 13 11:05:59 kernel: u_nsec 1 popcorn threshold 0 is 4*pps_jitter 0)
Apr 13 11:06:02 kernel: u_nsec 2 popcorn threshold 0 is 4*pps_jitter 0)
Apr 13 11:06:03 kernel: u_nsec 1 popcorn threshold 0 is 4*pps_jitter 0)
Apr 13 11:06:05 kernel: u_nsec 2 popcorn threshold 0 is 4*pps_jitter 0)
Apr 13 11:06:07 kernel: u_nsec 3 popcorn threshold 0 is 4*pps_jitter 0)
Apr 13 11:06:08 kernel: u_nsec 2 popcorn threshold 0 is 4*pps_jitter 0)
Apr 13 11:06:10 kernel: u_nsec 3 popcorn threshold 0 is 4*pps_jitter 0)
Apr 13 11:06:11 kernel: u_nsec 1 popcorn threshold 0 is 4*pps_jitter 0)

Our FreeBSD-based timekeeping products get into this pathological 
condition and ntpd fills syslog with "kernel time sync enabled" messages 
where the status bits continually toggle between 2101 and 2303 (the jitter 
bit toggles more or less at random every 16 seconds).

>How-To-Repeat:
	

>Fix:
The following patch uses two times the timer tick duration as a floor
value for the jitter threshold, so that a series of small-delta 
measurements don't cause subsequent small deltas to be counted as jitter.

It should apply cleanly to any FreeBSD version from 6.2 through -current.

Fix sponsored by: Symmetricom, Inc

--- patch-ppsjitter-kern_ntptime.c begins here ---
Index: sys/kern/kern_ntptime.c
===================================================================
RCS file: /local/base/FreeBSD-CVS/src/sys/kern/kern_ntptime.c,v
retrieving revision 1.71
diff -u -p -r1.71 kern_ntptime.c
--- sys/kern/kern_ntptime.c	25 Feb 2011 10:11:01 -0000	1.71
+++ sys/kern/kern_ntptime.c	18 Apr 2011 18:54:51 -0000
@@ -828,8 +828,15 @@ hardpps(tsp, nsec)
 	 * discarded. otherwise, if so enabled, the time offset is
 	 * updated. We can tolerate a modest loss of data here without
 	 * much degrading time accuracy.
+	 *
+	 * The measurements being checked here were made with the system
+	 * timecounter, so the popcorn threshold is not allowed to fall below
+	 * the number of nanoseconds in two ticks of the timecounter.  For a
+	 * timecounter running faster than 1 GHz the lower bound is 2ns, just
+	 * to avoid a nonsensical threshold of zero.
 	 */
-	if (u_nsec > (pps_jitter << PPS_POPCORN)) {
+	if (u_nsec > lmax(pps_jitter << PPS_POPCORN, 
+	    2 * (NANOSECOND / (long)qmin(NANOSECOND, tc_getfrequency())))) {
 		time_status |= STA_PPSJITTER;
 		pps_jitcnt++;
 	} else if (time_status & STA_PPSTIME) {
--- patch-ppsjitter-kern_ntptime.c ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104181932.p3IJW3HP059660>