[PATCH] my first attempt at reworking bigadjust for nohz

From: John Stultz
Date: Fri Dec 06 2013 - 20:25:21 EST


Takes a similar approach as Miroslav's but using the bigadjust method.

Signed-off-by: John Stultz <john.stultz@xxxxxxxxxx>
---
kernel/time/timekeeping.c | 80 +++++++++++++----------------------------------
1 file changed, 22 insertions(+), 58 deletions(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 947ba25..46f4bd2 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1056,42 +1056,24 @@ static __always_inline int timekeeping_bigadjust(struct timekeeper *tk,
s64 *offset)
{
s64 tick_error, i;
- u32 look_ahead, adj;
- s32 error2, mult;
+ u32 adj;
+ s32 mult = 1;

- /*
- * Use the current error value to determine how much to look ahead.
- * The larger the error the slower we adjust for it to avoid problems
- * with losing too many ticks, otherwise we would overadjust and
- * produce an even larger error. The smaller the adjustment the
- * faster we try to adjust for it, as lost ticks can do less harm
- * here. This is tuned so that an error of about 1 msec is adjusted
- * within about 1 sec (or 2^20 nsec in 2^SHIFT_HZ ticks).
- */
- error2 = tk->ntp_error >> (NTP_SCALE_SHIFT + 22 - 2 * SHIFT_HZ);
- error2 = abs(error2);
- for (look_ahead = 0; error2 > 0; look_ahead++)
- error2 >>= 2;
+ /* Calculate current tick error */
+ tick_error = ntp_tick_length() >> (tk->ntp_error_shift );
+ tick_error -= tk->xtime_interval;

- /*
- * Now calculate the error in (1 << look_ahead) ticks, but first
- * remove the single look ahead already included in the error.
- */
- tick_error = ntp_tick_length() >> (tk->ntp_error_shift + 1);
- tick_error -= tk->xtime_interval >> 1;
- error = ((error - tick_error) >> look_ahead) + tick_error;
-
- /* Finally calculate the adjustment shift value. */
- i = *interval;
- mult = 1;
- if (error < 0) {
- error = -error;
+ if (tick_error < 0) {
*interval = -*interval;
*offset = -*offset;
- mult = -1;
+ mult = -mult;
}
- for (adj = 0; error > i; adj++)
- error >>= 1;
+
+ /* Sort out the magnitude of the correction */
+ tick_error = abs(tick_error);
+ i = abs(*interval);
+ for (adj = 0; tick_error > i; adj++)
+ tick_error >>= 1;

*interval <<= adj;
*offset <<= adj;
@@ -1114,41 +1096,23 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
*
* First we shift it down from NTP_SHIFT to clocksource->shifted nsecs.
*
- * Note we subtract one in the shift, so that error is really error*2.
- * This "saves" dividing(shifting) interval twice, but keeps the
- * (error > interval) comparison as still measuring if error is
- * larger than half an interval.
- *
- * Note: It does not "save" on aggravation when reading the code.
+ * Then we meausre if error is larger than half an interval.
*/
- error = tk->ntp_error >> (tk->ntp_error_shift - 1);
- if (error > interval) {
- /*
- * We now divide error by 4(via shift), which checks if
- * the error is greater than twice the interval.
- * If it is greater, we need a bigadjust, if its smaller,
- * we can adjust by 1.
- */
- error >>= 2;
+ error = tk->ntp_error >> (tk->ntp_error_shift);
+ if (error > interval/2) {
/*
- * XXX - In update_wall_time, we round up to the next
- * nanosecond, and store the amount rounded up into
- * the error. This causes the likely below to be unlikely.
- *
- * The proper fix is to avoid rounding up by using
- * the high precision tk->xtime_nsec instead of
- * xtime.tv_nsec everywhere. Fixing this will take some
- * time.
+ * We now checks if the error is greater than twice the
+ * interval. If it is greater, we need a bigadjust, if its
+ * smaller, we can adjust by 1.
*/
- if (likely(error <= interval))
+ if (likely(error <= interval*2))
adj = 1;
else
adj = timekeeping_bigadjust(tk, error, &interval, &offset);
} else {
- if (error < -interval) {
+ if (error < -interval/2) {
/* See comment above, this is just switched for the negative */
- error >>= 2;
- if (likely(error >= -interval)) {
+ if (likely(error >= -interval*2)) {
adj = -1;
interval = -interval;
offset = -offset;
--
1.8.3.2


--------------030509040108020001000106--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/