Commit f4304ab21513b834c8fe3403927c60c2b81a72d7
Committed by
Linus Torvalds
1 parent
771ee3b04e
Exists in
master
and in
4 other branches
[PATCH] HZ free ntp
Distangle the NTP update from HZ. This is necessary for dynamic tick enabled kernels. Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@elte.hu> Cc: john stultz <johnstul@us.ibm.com> Cc: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 4 changed files with 36 additions and 16 deletions Side-by-side Diff
include/linux/timex.h
... | ... | @@ -286,6 +286,13 @@ |
286 | 286 | |
287 | 287 | #define TICK_LENGTH_SHIFT 32 |
288 | 288 | |
289 | +#ifdef CONFIG_NO_HZ | |
290 | +#define NTP_INTERVAL_FREQ (2) | |
291 | +#else | |
292 | +#define NTP_INTERVAL_FREQ (HZ) | |
293 | +#endif | |
294 | +#define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ) | |
295 | + | |
289 | 296 | /* Returns how long ticks are at present, in ns / 2^(SHIFT_SCALE-10). */ |
290 | 297 | extern u64 current_tick_length(void); |
291 | 298 |
kernel/hrtimer.c
... | ... | @@ -128,15 +128,20 @@ |
128 | 128 | static void hrtimer_get_softirq_time(struct hrtimer_base *base) |
129 | 129 | { |
130 | 130 | ktime_t xtim, tomono; |
131 | + struct timespec xts; | |
131 | 132 | unsigned long seq; |
132 | 133 | |
133 | 134 | do { |
134 | 135 | seq = read_seqbegin(&xtime_lock); |
135 | - xtim = timespec_to_ktime(xtime); | |
136 | - tomono = timespec_to_ktime(wall_to_monotonic); | |
137 | - | |
136 | +#ifdef CONFIG_NO_HZ | |
137 | + getnstimeofday(&xts); | |
138 | +#else | |
139 | + xts = xtime; | |
140 | +#endif | |
138 | 141 | } while (read_seqretry(&xtime_lock, seq)); |
139 | 142 | |
143 | + xtim = timespec_to_ktime(xts); | |
144 | + tomono = timespec_to_ktime(wall_to_monotonic); | |
140 | 145 | base[CLOCK_REALTIME].softirq_time = xtim; |
141 | 146 | base[CLOCK_MONOTONIC].softirq_time = ktime_add(xtim, tomono); |
142 | 147 | } |
kernel/time/ntp.c
... | ... | @@ -24,7 +24,7 @@ |
24 | 24 | |
25 | 25 | #define MAX_TICKADJ 500 /* microsecs */ |
26 | 26 | #define MAX_TICKADJ_SCALED (((u64)(MAX_TICKADJ * NSEC_PER_USEC) << \ |
27 | - TICK_LENGTH_SHIFT) / HZ) | |
27 | + TICK_LENGTH_SHIFT) / NTP_INTERVAL_FREQ) | |
28 | 28 | |
29 | 29 | /* |
30 | 30 | * phase-lock loop variables |
31 | 31 | |
32 | 32 | |
... | ... | @@ -46,13 +46,17 @@ |
46 | 46 | |
47 | 47 | static void ntp_update_frequency(void) |
48 | 48 | { |
49 | - tick_length_base = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << TICK_LENGTH_SHIFT; | |
50 | - tick_length_base += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT; | |
51 | - tick_length_base += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC); | |
49 | + u64 second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) | |
50 | + << TICK_LENGTH_SHIFT; | |
51 | + second_length += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT; | |
52 | + second_length += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC); | |
52 | 53 | |
53 | - do_div(tick_length_base, HZ); | |
54 | + tick_length_base = second_length; | |
54 | 55 | |
55 | - tick_nsec = tick_length_base >> TICK_LENGTH_SHIFT; | |
56 | + do_div(second_length, HZ); | |
57 | + tick_nsec = second_length >> TICK_LENGTH_SHIFT; | |
58 | + | |
59 | + do_div(tick_length_base, NTP_INTERVAL_FREQ); | |
56 | 60 | } |
57 | 61 | |
58 | 62 | /** |
... | ... | @@ -162,7 +166,7 @@ |
162 | 166 | tick_length -= MAX_TICKADJ_SCALED; |
163 | 167 | } else { |
164 | 168 | tick_length += (s64)(time_adjust * NSEC_PER_USEC / |
165 | - HZ) << TICK_LENGTH_SHIFT; | |
169 | + NTP_INTERVAL_FREQ) << TICK_LENGTH_SHIFT; | |
166 | 170 | time_adjust = 0; |
167 | 171 | } |
168 | 172 | } |
... | ... | @@ -239,7 +243,8 @@ |
239 | 243 | result = -EINVAL; |
240 | 244 | goto leave; |
241 | 245 | } |
242 | - time_freq = ((s64)txc->freq * NSEC_PER_USEC) >> (SHIFT_USEC - SHIFT_NSEC); | |
246 | + time_freq = ((s64)txc->freq * NSEC_PER_USEC) | |
247 | + >> (SHIFT_USEC - SHIFT_NSEC); | |
243 | 248 | } |
244 | 249 | |
245 | 250 | if (txc->modes & ADJ_MAXERROR) { |
... | ... | @@ -309,7 +314,8 @@ |
309 | 314 | freq_adj += time_freq; |
310 | 315 | freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC); |
311 | 316 | time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC); |
312 | - time_offset = (time_offset / HZ) << SHIFT_UPDATE; | |
317 | + time_offset = (time_offset / NTP_INTERVAL_FREQ) | |
318 | + << SHIFT_UPDATE; | |
313 | 319 | } /* STA_PLL */ |
314 | 320 | } /* txc->modes & ADJ_OFFSET */ |
315 | 321 | if (txc->modes & ADJ_TICK) |
... | ... | @@ -324,8 +330,10 @@ |
324 | 330 | if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT) |
325 | 331 | txc->offset = save_adjust; |
326 | 332 | else |
327 | - txc->offset = shift_right(time_offset, SHIFT_UPDATE) * HZ / 1000; | |
328 | - txc->freq = (time_freq / NSEC_PER_USEC) << (SHIFT_USEC - SHIFT_NSEC); | |
333 | + txc->offset = shift_right(time_offset, SHIFT_UPDATE) | |
334 | + * NTP_INTERVAL_FREQ / 1000; | |
335 | + txc->freq = (time_freq / NSEC_PER_USEC) | |
336 | + << (SHIFT_USEC - SHIFT_NSEC); | |
329 | 337 | txc->maxerror = time_maxerror; |
330 | 338 | txc->esterror = time_esterror; |
331 | 339 | txc->status = time_status; |
kernel/timer.c
... | ... | @@ -890,7 +890,7 @@ |
890 | 890 | ntp_clear(); |
891 | 891 | |
892 | 892 | clock = clocksource_get_next(); |
893 | - clocksource_calculate_interval(clock, tick_nsec); | |
893 | + clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); | |
894 | 894 | clock->cycle_last = clocksource_read(clock); |
895 | 895 | |
896 | 896 | write_sequnlock_irqrestore(&xtime_lock, flags); |
... | ... | @@ -1092,7 +1092,7 @@ |
1092 | 1092 | if (change_clocksource()) { |
1093 | 1093 | clock->error = 0; |
1094 | 1094 | clock->xtime_nsec = 0; |
1095 | - clocksource_calculate_interval(clock, tick_nsec); | |
1095 | + clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); | |
1096 | 1096 | } |
1097 | 1097 | } |
1098 | 1098 |