From owner-svn-src-stable-10@freebsd.org Wed Jul 15 19:11:44 2015 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C79E49A215D; Wed, 15 Jul 2015 19:11:44 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A64451E84; Wed, 15 Jul 2015 19:11:44 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from svnmir.geo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.14.9/8.14.9) with ESMTP id t6FJBi34025629; Wed, 15 Jul 2015 19:11:44 GMT (envelope-from delphij@FreeBSD.org) Received: (from delphij@localhost) by svnmir.geo.freebsd.org (8.14.9/8.14.9/Submit) id t6FJBiCg025628; Wed, 15 Jul 2015 19:11:44 GMT (envelope-from delphij@FreeBSD.org) Message-Id: <201507151911.t6FJBiCg025628@svnmir.geo.freebsd.org> X-Authentication-Warning: svnmir.geo.freebsd.org: delphij set sender to delphij@FreeBSD.org using -f From: Xin LI Date: Wed, 15 Jul 2015 19:11:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r285611 - stable/10/sys/kern X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Jul 2015 19:11:45 -0000 Author: delphij Date: Wed Jul 15 19:11:43 2015 New Revision: 285611 URL: https://svnweb.freebsd.org/changeset/base/285611 Log: MFC r285424 (ian): Use the monotonic (uptime) counter rather than time-of-day to measure elapsed time between ntp_adjtime() clock offset adjustments. This eliminates spurious frequency steering after a large clock step (such as a 1970->2015 step on a system with no battery-backed clock hardware). This problem was discovered after the import of ntpd 4.2.8, which does things in a slightly different (but still correct) order than the 4.2.4 we had previously. In particular, 4.2.4 would step the clock then immediately after use ntp_adjtime() to set the frequency and offset to zero, which captured the post-step time-of-day as a side effect. In 4.2.8, ntpd sets frequency and offset to zero before any initial clock step, capturing the time as 1970-ish, then when it next calls ntp_adjtime() it's with a non-zero offset measurement. This non-zero value gets multiplied by the apparent 45-year interval, which blows up into a completely bogus frequency steer. That gets clamped to 500ppm, but that's still enough to make the clock drift so fast that ntpd has to keep stepping it every few minutes to compensate. Approved by: re (gjb) Modified: stable/10/sys/kern/kern_ntptime.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/kern/kern_ntptime.c ============================================================================== --- stable/10/sys/kern/kern_ntptime.c Wed Jul 15 18:49:15 2015 (r285610) +++ stable/10/sys/kern/kern_ntptime.c Wed Jul 15 19:11:43 2015 (r285611) @@ -155,7 +155,7 @@ static long time_constant; /* poll inte static long time_precision = 1; /* clock precision (ns) */ static long time_maxerror = MAXPHASE / 1000; /* maximum error (us) */ long time_esterror = MAXPHASE / 1000; /* estimated error (us) */ -static long time_reftime; /* time at last adjustment (s) */ +static long time_reftime; /* uptime at last adjustment (s) */ static l_fp time_offset; /* time offset (ns) */ static l_fp time_freq; /* frequency offset (ns/s) */ static l_fp time_adj; /* tick adjust (ns/s) */ @@ -696,12 +696,12 @@ hardupdate(offset) * otherwise, the argument offset is used to compute it. */ if (time_status & STA_PPSFREQ && time_status & STA_PPSSIGNAL) { - time_reftime = time_second; + time_reftime = time_uptime; return; } if (time_status & STA_FREQHOLD || time_reftime == 0) - time_reftime = time_second; - mtemp = time_second - time_reftime; + time_reftime = time_uptime; + mtemp = time_uptime - time_reftime; L_LINT(ftemp, time_monitor); L_RSHIFT(ftemp, (SHIFT_PLL + 2 + time_constant) << 1); L_MPY(ftemp, mtemp); @@ -714,7 +714,7 @@ hardupdate(offset) L_ADD(time_freq, ftemp); time_status |= STA_MODE; } - time_reftime = time_second; + time_reftime = time_uptime; if (L_GINT(time_freq) > MAXFREQ) L_LINT(time_freq, MAXFREQ); else if (L_GINT(time_freq) < -MAXFREQ)