aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/timekeeper_internal.h
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2013-12-06 17:25:21 -0800
committerJohn Stultz <john.stultz@linaro.org>2014-07-23 15:01:56 -0700
commitdc491596f6394382fbc74ad331156207d619fa0a (patch)
treec5496cc0145eaeea40e42aac5e2baecc0a7923d0 /include/linux/timekeeper_internal.h
parenttimekeeping: Minor fixup for timespec64->timespec assignment (diff)
downloadlinux-dev-dc491596f6394382fbc74ad331156207d619fa0a.tar.xz
linux-dev-dc491596f6394382fbc74ad331156207d619fa0a.zip
timekeeping: Rework frequency adjustments to work better w/ nohz
The existing timekeeping_adjust logic has always been complicated to understand. Further, since it was developed prior to NOHZ becoming common, its not surprising it performs poorly when NOHZ is enabled. Since Miroslav pointed out the problematic nature of the existing code in the NOHZ case, I've tried to refactor the code to perform better. The problem with the previous approach was that it tried to adjust for the total cumulative error using a scaled dampening factor. This resulted in large errors to be corrected slowly, while small errors were corrected quickly. With NOHZ the timekeeping code doesn't know how far out the next tick will be, so this results in bad over-correction to small errors, and insufficient correction to large errors. Inspired by Miroslav's patch, I've refactored the code to try to address the correction in two steps. 1) Check the future freq error for the next tick, and if the frequency error is large, try to make sure we correct it so it doesn't cause much accumulated error. 2) Then make a small single unit adjustment to correct any cumulative error that has collected over time. This method performs fairly well in the simulator Miroslav created. Major credit to Miroslav for pointing out the issue, providing the original patch to resolve this, a simulator for testing, as well as helping debug and resolve issues in my implementation so that it performed closer to his original implementation. Cc: Miroslav Lichvar <mlichvar@redhat.com> Cc: Richard Cochran <richardcochran@gmail.com> Cc: Prarit Bhargava <prarit@redhat.com> Reported-by: Miroslav Lichvar <mlichvar@redhat.com> Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'include/linux/timekeeper_internal.h')
-rw-r--r--include/linux/timekeeper_internal.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index 97381997625b..f7ac48d2edf5 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -92,6 +92,7 @@ struct timekeeper {
u32 raw_interval;
s64 ntp_error;
u32 ntp_error_shift;
+ u32 ntp_err_mult;
};
#ifdef CONFIG_GENERIC_TIME_VSYSCALL