Commit f4304ab21513b834c8fe3403927c60c2b81a72d7

Authored by john stultz
Committed by Linus Torvalds
1 parent 771ee3b04e

[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  
... ... @@ -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 }
... ... @@ -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;
... ... @@ -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