aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2009-08-14 09:47:28 -0400
committerThomas Gleixner <tglx@linutronix.de>2009-08-15 04:55:46 -0400
commit0a54419836254a27baecd9037103171bcbabaf67 (patch)
treead4dc7ca1fc974a53c7fc2e972558bcb6b786afe /kernel
parent23ce72117c714baab794e66c8daf343bf6a912bf (diff)
timekeeping: Move NTP adjusted clock multiplier to struct timekeeper
The clocksource structure has two multipliers, the unmodified multiplier clock->mult_orig and the NTP corrected multiplier clock->mult. The NTP multiplier is misplaced in the struct clocksource, this is private information of the timekeeping code. Add the mult field to the struct timekeeper to contain the NTP corrected value, keep the unmodifed multiplier in clock->mult and remove clock->mult_orig. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Ingo Molnar <mingo@elte.hu> Acked-by: John Stultz <johnstul@us.ibm.com> Cc: Daniel Walker <dwalker@fifo99.com> LKML-Reference: <20090814134810.149047645@de.ibm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time/timekeeping.c53
1 files changed, 24 insertions, 29 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index dfdab1cefe1e..f4056f6c2632 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -41,6 +41,8 @@ struct timekeeper {
41 /* Shift conversion between clock shifted nano seconds and 41 /* Shift conversion between clock shifted nano seconds and
42 * ntp shifted nano seconds. */ 42 * ntp shifted nano seconds. */
43 int ntp_error_shift; 43 int ntp_error_shift;
44 /* NTP adjusted clock multiplier */
45 u32 mult;
44}; 46};
45 47
46struct timekeeper timekeeper; 48struct timekeeper timekeeper;
@@ -66,8 +68,8 @@ static void timekeeper_setup_internals(struct clocksource *clock)
66 /* Do the ns -> cycle conversion first, using original mult */ 68 /* Do the ns -> cycle conversion first, using original mult */
67 tmp = NTP_INTERVAL_LENGTH; 69 tmp = NTP_INTERVAL_LENGTH;
68 tmp <<= clock->shift; 70 tmp <<= clock->shift;
69 tmp += clock->mult_orig/2; 71 tmp += clock->mult/2;
70 do_div(tmp, clock->mult_orig); 72 do_div(tmp, clock->mult);
71 if (tmp == 0) 73 if (tmp == 0)
72 tmp = 1; 74 tmp = 1;
73 75
@@ -77,13 +79,20 @@ static void timekeeper_setup_internals(struct clocksource *clock)
77 /* Go back from cycles -> shifted ns */ 79 /* Go back from cycles -> shifted ns */
78 timekeeper.xtime_interval = (u64) interval * clock->mult; 80 timekeeper.xtime_interval = (u64) interval * clock->mult;
79 timekeeper.raw_interval = 81 timekeeper.raw_interval =
80 ((u64) interval * clock->mult_orig) >> clock->shift; 82 ((u64) interval * clock->mult) >> clock->shift;
81 83
82 timekeeper.xtime_nsec = 0; 84 timekeeper.xtime_nsec = 0;
83 timekeeper.shift = clock->shift; 85 timekeeper.shift = clock->shift;
84 86
85 timekeeper.ntp_error = 0; 87 timekeeper.ntp_error = 0;
86 timekeeper.ntp_error_shift = NTP_SCALE_SHIFT - clock->shift; 88 timekeeper.ntp_error_shift = NTP_SCALE_SHIFT - clock->shift;
89
90 /*
91 * The timekeeper keeps its own mult values for the currently
92 * active clocksource. These value will be adjusted via NTP
93 * to counteract clock drifting.
94 */
95 timekeeper.mult = clock->mult;
87} 96}
88 97
89/* 98/*
@@ -154,14 +163,15 @@ static void timekeeping_forward_now(void)
154 cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; 163 cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
155 clock->cycle_last = cycle_now; 164 clock->cycle_last = cycle_now;
156 165
157 nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift); 166 nsec = clocksource_cyc2ns(cycle_delta, timekeeper.mult,
167 timekeeper.shift);
158 168
159 /* If arch requires, add in gettimeoffset() */ 169 /* If arch requires, add in gettimeoffset() */
160 nsec += arch_gettimeoffset(); 170 nsec += arch_gettimeoffset();
161 171
162 timespec_add_ns(&xtime, nsec); 172 timespec_add_ns(&xtime, nsec);
163 173
164 nsec = clocksource_cyc2ns(cycle_delta, clock->mult_orig, clock->shift); 174 nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift);
165 timespec_add_ns(&raw_time, nsec); 175 timespec_add_ns(&raw_time, nsec);
166} 176}
167 177
@@ -193,8 +203,8 @@ void getnstimeofday(struct timespec *ts)
193 cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; 203 cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
194 204
195 /* convert to nanoseconds: */ 205 /* convert to nanoseconds: */
196 nsecs = clocksource_cyc2ns(cycle_delta, clock->mult, 206 nsecs = clocksource_cyc2ns(cycle_delta, timekeeper.mult,
197 clock->shift); 207 timekeeper.shift);
198 208
199 /* If arch requires, add in gettimeoffset() */ 209 /* If arch requires, add in gettimeoffset() */
200 nsecs += arch_gettimeoffset(); 210 nsecs += arch_gettimeoffset();
@@ -228,8 +238,8 @@ ktime_t ktime_get(void)
228 cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; 238 cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
229 239
230 /* convert to nanoseconds: */ 240 /* convert to nanoseconds: */
231 nsecs += clocksource_cyc2ns(cycle_delta, clock->mult, 241 nsecs += clocksource_cyc2ns(cycle_delta, timekeeper.mult,
232 clock->shift); 242 timekeeper.shift);
233 243
234 } while (read_seqretry(&xtime_lock, seq)); 244 } while (read_seqretry(&xtime_lock, seq));
235 /* 245 /*
@@ -271,8 +281,8 @@ void ktime_get_ts(struct timespec *ts)
271 cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; 281 cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
272 282
273 /* convert to nanoseconds: */ 283 /* convert to nanoseconds: */
274 nsecs = clocksource_cyc2ns(cycle_delta, clock->mult, 284 nsecs = clocksource_cyc2ns(cycle_delta, timekeeper.mult,
275 clock->shift); 285 timekeeper.shift);
276 286
277 } while (read_seqretry(&xtime_lock, seq)); 287 } while (read_seqretry(&xtime_lock, seq));
278 288
@@ -356,22 +366,10 @@ static void change_clocksource(void)
356 366
357 if (new->enable && !new->enable(new)) 367 if (new->enable && !new->enable(new))
358 return; 368 return;
359 /*
360 * The frequency may have changed while the clocksource
361 * was disabled. If so the code in ->enable() must update
362 * the mult value to reflect the new frequency. Make sure
363 * mult_orig follows this change.
364 */
365 new->mult_orig = new->mult;
366 369
367 old = timekeeper.clock; 370 old = timekeeper.clock;
368 timekeeper_setup_internals(new); 371 timekeeper_setup_internals(new);
369 372
370 /*
371 * Save mult_orig in mult so that the value can be restored
372 * regardless if ->enable() updates the value of mult or not.
373 */
374 old->mult = old->mult_orig;
375 if (old->disable) 373 if (old->disable)
376 old->disable(old); 374 old->disable(old);
377 375
@@ -461,7 +459,7 @@ void getrawmonotonic(struct timespec *ts)
461 cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; 459 cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
462 460
463 /* convert to nanoseconds: */ 461 /* convert to nanoseconds: */
464 nsecs = clocksource_cyc2ns(cycle_delta, clock->mult_orig, 462 nsecs = clocksource_cyc2ns(cycle_delta, clock->mult,
465 clock->shift); 463 clock->shift);
466 464
467 *ts = raw_time; 465 *ts = raw_time;
@@ -521,9 +519,6 @@ void __init timekeeping_init(void)
521 clock = clocksource_default_clock(); 519 clock = clocksource_default_clock();
522 if (clock->enable) 520 if (clock->enable)
523 clock->enable(clock); 521 clock->enable(clock);
524 /* set mult_orig on enable */
525 clock->mult_orig = clock->mult;
526
527 timekeeper_setup_internals(clock); 522 timekeeper_setup_internals(clock);
528 523
529 xtime.tv_sec = sec; 524 xtime.tv_sec = sec;
@@ -697,7 +692,7 @@ static void timekeeping_adjust(s64 offset)
697 } else 692 } else
698 return; 693 return;
699 694
700 timekeeper.clock->mult += adj; 695 timekeeper.mult += adj;
701 timekeeper.xtime_interval += interval; 696 timekeeper.xtime_interval += interval;
702 timekeeper.xtime_nsec -= offset; 697 timekeeper.xtime_nsec -= offset;
703 timekeeper.ntp_error -= (interval - offset) << 698 timekeeper.ntp_error -= (interval - offset) <<
@@ -789,7 +784,7 @@ void update_wall_time(void)
789 timekeeper.ntp_error += timekeeper.xtime_nsec << 784 timekeeper.ntp_error += timekeeper.xtime_nsec <<
790 timekeeper.ntp_error_shift; 785 timekeeper.ntp_error_shift;
791 786
792 nsecs = clocksource_cyc2ns(offset, clock->mult, clock->shift); 787 nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift);
793 update_xtime_cache(nsecs); 788 update_xtime_cache(nsecs);
794 789
795 /* check to see if there is a new clocksource to use */ 790 /* check to see if there is a new clocksource to use */