summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiroslav Lichvar <mlichvar@redhat.com>2010-09-07 16:43:46 +0200
committerThomas Gleixner <tglx@linutronix.de>2010-09-09 20:48:37 +0200
commit8af3c153baf95374eff20a37f00c59a295b52756 (patch)
treedb80f770b668f7067c3e95af92cc92933edce4e0
parentMerge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jba... (diff)
downloadlinux-8af3c153baf95374eff20a37f00c59a295b52756.tar.xz
linux-8af3c153baf95374eff20a37f00c59a295b52756.zip
ntp: Clamp PLL update interval
Clamp update interval to reduce PLL gain with low sampling rate (e.g. intermittent network connection) to avoid instability. The clamp roughly corresponds to the loop time constant, it's 8 * poll interval for SHIFT_PLL 2 and 32 * poll interval for SHIFT_PLL 4. This gives good results without affecting the gain in normal conditions where ntpd skips only up to seven consecutive samples. Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com> Acked-by: john stultz <johnstul@us.ibm.com> LKML-Reference: <1283870626-9472-1-git-send-email-mlichvar@redhat.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--kernel/time/ntp.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index c63116863a80..d2321891538f 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -149,10 +149,18 @@ static void ntp_update_offset(long offset)
time_reftime = get_seconds();
offset64 = offset;
- freq_adj = (offset64 * secs) <<
- (NTP_SCALE_SHIFT - 2 * (SHIFT_PLL + 2 + time_constant));
+ freq_adj = ntp_update_offset_fll(offset64, secs);
- freq_adj += ntp_update_offset_fll(offset64, secs);
+ /*
+ * Clamp update interval to reduce PLL gain with low
+ * sampling rate (e.g. intermittent network connection)
+ * to avoid instability.
+ */
+ if (unlikely(secs > 1 << (SHIFT_PLL + 1 + time_constant)))
+ secs = 1 << (SHIFT_PLL + 1 + time_constant);
+
+ freq_adj += (offset64 * secs) <<
+ (NTP_SCALE_SHIFT - 2 * (SHIFT_PLL + 2 + time_constant));
freq_adj = min(freq_adj + time_freq, MAXFREQ_SCALED);