Commit 7c526e1fef8d604a9ec022d9145bba5dbfe40a11
Exists in
master
and in
39 other branches
Merge branches 'timers/new-apis', 'timers/ntp' and 'timers/urgent' into timers/core
Showing 8 changed files Side-by-side Diff
arch/powerpc/platforms/cell/spufs/sched.c
... | ... | @@ -508,7 +508,7 @@ |
508 | 508 | list_add_tail(&ctx->rq, &spu_prio->runq[ctx->prio]); |
509 | 509 | set_bit(ctx->prio, spu_prio->bitmap); |
510 | 510 | if (!spu_prio->nr_waiting++) |
511 | - __mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK); | |
511 | + mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK); | |
512 | 512 | } |
513 | 513 | } |
514 | 514 |
drivers/infiniband/hw/ipath/ipath_driver.c
... | ... | @@ -2715,7 +2715,7 @@ |
2715 | 2715 | * to prevent HoL blocking, then start the HoL timer that |
2716 | 2716 | * periodically continues, then stop procs, so they can detect |
2717 | 2717 | * link down if they want, and do something about it. |
2718 | - * Timer may already be running, so use __mod_timer, not add_timer. | |
2718 | + * Timer may already be running, so use mod_timer, not add_timer. | |
2719 | 2719 | */ |
2720 | 2720 | void ipath_hol_down(struct ipath_devdata *dd) |
2721 | 2721 | { |
... | ... | @@ -2724,7 +2724,7 @@ |
2724 | 2724 | dd->ipath_hol_next = IPATH_HOL_DOWNCONT; |
2725 | 2725 | dd->ipath_hol_timer.expires = jiffies + |
2726 | 2726 | msecs_to_jiffies(ipath_hol_timeout_ms); |
2727 | - __mod_timer(&dd->ipath_hol_timer, dd->ipath_hol_timer.expires); | |
2727 | + mod_timer(&dd->ipath_hol_timer, dd->ipath_hol_timer.expires); | |
2728 | 2728 | } |
2729 | 2729 | |
2730 | 2730 | /* |
... | ... | @@ -2763,7 +2763,7 @@ |
2763 | 2763 | else { |
2764 | 2764 | dd->ipath_hol_timer.expires = jiffies + |
2765 | 2765 | msecs_to_jiffies(ipath_hol_timeout_ms); |
2766 | - __mod_timer(&dd->ipath_hol_timer, | |
2766 | + mod_timer(&dd->ipath_hol_timer, | |
2767 | 2767 | dd->ipath_hol_timer.expires); |
2768 | 2768 | } |
2769 | 2769 | } |
include/linux/timer.h
... | ... | @@ -86,8 +86,8 @@ |
86 | 86 | |
87 | 87 | extern void add_timer_on(struct timer_list *timer, int cpu); |
88 | 88 | extern int del_timer(struct timer_list * timer); |
89 | -extern int __mod_timer(struct timer_list *timer, unsigned long expires); | |
90 | 89 | extern int mod_timer(struct timer_list *timer, unsigned long expires); |
90 | +extern int mod_timer_pending(struct timer_list *timer, unsigned long expires); | |
91 | 91 | |
92 | 92 | /* |
93 | 93 | * The jiffies value which is added to now, when there is no timer |
... | ... | @@ -146,25 +146,7 @@ |
146 | 146 | } |
147 | 147 | #endif |
148 | 148 | |
149 | -/** | |
150 | - * add_timer - start a timer | |
151 | - * @timer: the timer to be added | |
152 | - * | |
153 | - * The kernel will do a ->function(->data) callback from the | |
154 | - * timer interrupt at the ->expires point in the future. The | |
155 | - * current time is 'jiffies'. | |
156 | - * | |
157 | - * The timer's ->expires, ->function (and if the handler uses it, ->data) | |
158 | - * fields must be set prior calling this function. | |
159 | - * | |
160 | - * Timers with an ->expires field in the past will be executed in the next | |
161 | - * timer tick. | |
162 | - */ | |
163 | -static inline void add_timer(struct timer_list *timer) | |
164 | -{ | |
165 | - BUG_ON(timer_pending(timer)); | |
166 | - __mod_timer(timer, timer->expires); | |
167 | -} | |
149 | +extern void add_timer(struct timer_list *timer); | |
168 | 150 | |
169 | 151 | #ifdef CONFIG_SMP |
170 | 152 | extern int try_to_del_timer_sync(struct timer_list *timer); |
include/linux/timex.h
... | ... | @@ -190,7 +190,7 @@ |
190 | 190 | * offset and maximum frequency tolerance. |
191 | 191 | */ |
192 | 192 | #define SHIFT_USEC 16 /* frequency offset scale (shift) */ |
193 | -#define PPM_SCALE (NSEC_PER_USEC << (NTP_SCALE_SHIFT - SHIFT_USEC)) | |
193 | +#define PPM_SCALE ((s64)NSEC_PER_USEC << (NTP_SCALE_SHIFT - SHIFT_USEC)) | |
194 | 194 | #define PPM_SCALE_INV_SHIFT 19 |
195 | 195 | #define PPM_SCALE_INV ((1ll << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \ |
196 | 196 | PPM_SCALE + 1) |
kernel/posix-cpu-timers.c
kernel/relay.c
kernel/time/ntp.c
1 | 1 | /* |
2 | - * linux/kernel/time/ntp.c | |
3 | - * | |
4 | 2 | * NTP state machine interfaces and logic. |
5 | 3 | * |
6 | 4 | * This code was mainly moved from kernel/timer.c and kernel/time.c |
7 | 5 | * Please see those files for relevant copyright info and historical |
8 | 6 | * changelogs. |
9 | 7 | */ |
10 | - | |
11 | -#include <linux/mm.h> | |
12 | -#include <linux/time.h> | |
13 | -#include <linux/timex.h> | |
14 | -#include <linux/jiffies.h> | |
15 | -#include <linux/hrtimer.h> | |
16 | 8 | #include <linux/capability.h> |
17 | -#include <linux/math64.h> | |
18 | 9 | #include <linux/clocksource.h> |
19 | 10 | #include <linux/workqueue.h> |
20 | -#include <asm/timex.h> | |
11 | +#include <linux/hrtimer.h> | |
12 | +#include <linux/jiffies.h> | |
13 | +#include <linux/math64.h> | |
14 | +#include <linux/timex.h> | |
15 | +#include <linux/time.h> | |
16 | +#include <linux/mm.h> | |
21 | 17 | |
22 | 18 | /* |
23 | - * Timekeeping variables | |
19 | + * NTP timekeeping variables: | |
24 | 20 | */ |
25 | -unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */ | |
26 | -unsigned long tick_nsec; /* ACTHZ period (nsec) */ | |
27 | -u64 tick_length; | |
28 | -static u64 tick_length_base; | |
29 | 21 | |
30 | -static struct hrtimer leap_timer; | |
22 | +/* USER_HZ period (usecs): */ | |
23 | +unsigned long tick_usec = TICK_USEC; | |
31 | 24 | |
32 | -#define MAX_TICKADJ 500 /* microsecs */ | |
33 | -#define MAX_TICKADJ_SCALED (((u64)(MAX_TICKADJ * NSEC_PER_USEC) << \ | |
34 | - NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ) | |
25 | +/* ACTHZ period (nsecs): */ | |
26 | +unsigned long tick_nsec; | |
35 | 27 | |
28 | +u64 tick_length; | |
29 | +static u64 tick_length_base; | |
30 | + | |
31 | +static struct hrtimer leap_timer; | |
32 | + | |
33 | +#define MAX_TICKADJ 500LL /* usecs */ | |
34 | +#define MAX_TICKADJ_SCALED \ | |
35 | + (((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ) | |
36 | + | |
36 | 37 | /* |
37 | 38 | * phase-lock loop variables |
38 | 39 | */ |
39 | -/* TIME_ERROR prevents overwriting the CMOS clock */ | |
40 | -static int time_state = TIME_OK; /* clock synchronization status */ | |
41 | -int time_status = STA_UNSYNC; /* clock status bits */ | |
42 | -static long time_tai; /* TAI offset (s) */ | |
43 | -static s64 time_offset; /* time adjustment (ns) */ | |
44 | -static long time_constant = 2; /* pll time constant */ | |
45 | -long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */ | |
46 | -long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */ | |
47 | -static s64 time_freq; /* frequency offset (scaled ns/s)*/ | |
48 | -static long time_reftime; /* time at last adjustment (s) */ | |
49 | -long time_adjust; | |
50 | -static long ntp_tick_adj; | |
51 | 40 | |
41 | +/* | |
42 | + * clock synchronization status | |
43 | + * | |
44 | + * (TIME_ERROR prevents overwriting the CMOS clock) | |
45 | + */ | |
46 | +static int time_state = TIME_OK; | |
47 | + | |
48 | +/* clock status bits: */ | |
49 | +int time_status = STA_UNSYNC; | |
50 | + | |
51 | +/* TAI offset (secs): */ | |
52 | +static long time_tai; | |
53 | + | |
54 | +/* time adjustment (nsecs): */ | |
55 | +static s64 time_offset; | |
56 | + | |
57 | +/* pll time constant: */ | |
58 | +static long time_constant = 2; | |
59 | + | |
60 | +/* maximum error (usecs): */ | |
61 | +long time_maxerror = NTP_PHASE_LIMIT; | |
62 | + | |
63 | +/* estimated error (usecs): */ | |
64 | +long time_esterror = NTP_PHASE_LIMIT; | |
65 | + | |
66 | +/* frequency offset (scaled nsecs/secs): */ | |
67 | +static s64 time_freq; | |
68 | + | |
69 | +/* time at last adjustment (secs): */ | |
70 | +static long time_reftime; | |
71 | + | |
72 | +long time_adjust; | |
73 | + | |
74 | +/* constant (boot-param configurable) NTP tick adjustment (upscaled) */ | |
75 | +static s64 ntp_tick_adj; | |
76 | + | |
77 | +/* | |
78 | + * NTP methods: | |
79 | + */ | |
80 | + | |
81 | +/* | |
82 | + * Update (tick_length, tick_length_base, tick_nsec), based | |
83 | + * on (tick_usec, ntp_tick_adj, time_freq): | |
84 | + */ | |
52 | 85 | static void ntp_update_frequency(void) |
53 | 86 | { |
54 | - u64 second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) | |
55 | - << NTP_SCALE_SHIFT; | |
56 | - second_length += (s64)ntp_tick_adj << NTP_SCALE_SHIFT; | |
57 | - second_length += time_freq; | |
87 | + u64 second_length; | |
88 | + u64 new_base; | |
58 | 89 | |
59 | - tick_length_base = second_length; | |
90 | + second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) | |
91 | + << NTP_SCALE_SHIFT; | |
60 | 92 | |
61 | - tick_nsec = div_u64(second_length, HZ) >> NTP_SCALE_SHIFT; | |
62 | - tick_length_base = div_u64(tick_length_base, NTP_INTERVAL_FREQ); | |
93 | + second_length += ntp_tick_adj; | |
94 | + second_length += time_freq; | |
95 | + | |
96 | + tick_nsec = div_u64(second_length, HZ) >> NTP_SCALE_SHIFT; | |
97 | + new_base = div_u64(second_length, NTP_INTERVAL_FREQ); | |
98 | + | |
99 | + /* | |
100 | + * Don't wait for the next second_overflow, apply | |
101 | + * the change to the tick length immediately: | |
102 | + */ | |
103 | + tick_length += new_base - tick_length_base; | |
104 | + tick_length_base = new_base; | |
63 | 105 | } |
64 | 106 | |
107 | +static inline s64 ntp_update_offset_fll(s64 offset64, long secs) | |
108 | +{ | |
109 | + time_status &= ~STA_MODE; | |
110 | + | |
111 | + if (secs < MINSEC) | |
112 | + return 0; | |
113 | + | |
114 | + if (!(time_status & STA_FLL) && (secs <= MAXSEC)) | |
115 | + return 0; | |
116 | + | |
117 | + time_status |= STA_MODE; | |
118 | + | |
119 | + return div_s64(offset64 << (NTP_SCALE_SHIFT - SHIFT_FLL), secs); | |
120 | +} | |
121 | + | |
65 | 122 | static void ntp_update_offset(long offset) |
66 | 123 | { |
67 | - long mtemp; | |
68 | 124 | s64 freq_adj; |
125 | + s64 offset64; | |
126 | + long secs; | |
69 | 127 | |
70 | 128 | if (!(time_status & STA_PLL)) |
71 | 129 | return; |
72 | 130 | |
73 | 131 | |
... | ... | @@ -84,24 +142,23 @@ |
84 | 142 | * Select how the frequency is to be controlled |
85 | 143 | * and in which mode (PLL or FLL). |
86 | 144 | */ |
87 | - if (time_status & STA_FREQHOLD || time_reftime == 0) | |
88 | - time_reftime = xtime.tv_sec; | |
89 | - mtemp = xtime.tv_sec - time_reftime; | |
145 | + secs = xtime.tv_sec - time_reftime; | |
146 | + if (unlikely(time_status & STA_FREQHOLD)) | |
147 | + secs = 0; | |
148 | + | |
90 | 149 | time_reftime = xtime.tv_sec; |
91 | 150 | |
92 | - freq_adj = (s64)offset * mtemp; | |
93 | - freq_adj <<= NTP_SCALE_SHIFT - 2 * (SHIFT_PLL + 2 + time_constant); | |
94 | - time_status &= ~STA_MODE; | |
95 | - if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { | |
96 | - freq_adj += div_s64((s64)offset << (NTP_SCALE_SHIFT - SHIFT_FLL), | |
97 | - mtemp); | |
98 | - time_status |= STA_MODE; | |
99 | - } | |
100 | - freq_adj += time_freq; | |
101 | - freq_adj = min(freq_adj, MAXFREQ_SCALED); | |
102 | - time_freq = max(freq_adj, -MAXFREQ_SCALED); | |
151 | + offset64 = offset; | |
152 | + freq_adj = (offset64 * secs) << | |
153 | + (NTP_SCALE_SHIFT - 2 * (SHIFT_PLL + 2 + time_constant)); | |
103 | 154 | |
104 | - time_offset = div_s64((s64)offset << NTP_SCALE_SHIFT, NTP_INTERVAL_FREQ); | |
155 | + freq_adj += ntp_update_offset_fll(offset64, secs); | |
156 | + | |
157 | + freq_adj = min(freq_adj + time_freq, MAXFREQ_SCALED); | |
158 | + | |
159 | + time_freq = max(freq_adj, -MAXFREQ_SCALED); | |
160 | + | |
161 | + time_offset = div_s64(offset64 << NTP_SCALE_SHIFT, NTP_INTERVAL_FREQ); | |
105 | 162 | } |
106 | 163 | |
107 | 164 | /** |
108 | 165 | |
... | ... | @@ -111,15 +168,15 @@ |
111 | 168 | */ |
112 | 169 | void ntp_clear(void) |
113 | 170 | { |
114 | - time_adjust = 0; /* stop active adjtime() */ | |
115 | - time_status |= STA_UNSYNC; | |
116 | - time_maxerror = NTP_PHASE_LIMIT; | |
117 | - time_esterror = NTP_PHASE_LIMIT; | |
171 | + time_adjust = 0; /* stop active adjtime() */ | |
172 | + time_status |= STA_UNSYNC; | |
173 | + time_maxerror = NTP_PHASE_LIMIT; | |
174 | + time_esterror = NTP_PHASE_LIMIT; | |
118 | 175 | |
119 | 176 | ntp_update_frequency(); |
120 | 177 | |
121 | - tick_length = tick_length_base; | |
122 | - time_offset = 0; | |
178 | + tick_length = tick_length_base; | |
179 | + time_offset = 0; | |
123 | 180 | } |
124 | 181 | |
125 | 182 | /* |
... | ... | @@ -140,8 +197,8 @@ |
140 | 197 | xtime.tv_sec--; |
141 | 198 | wall_to_monotonic.tv_sec++; |
142 | 199 | time_state = TIME_OOP; |
143 | - printk(KERN_NOTICE "Clock: " | |
144 | - "inserting leap second 23:59:60 UTC\n"); | |
200 | + printk(KERN_NOTICE | |
201 | + "Clock: inserting leap second 23:59:60 UTC\n"); | |
145 | 202 | hrtimer_add_expires_ns(&leap_timer, NSEC_PER_SEC); |
146 | 203 | res = HRTIMER_RESTART; |
147 | 204 | break; |
... | ... | @@ -150,8 +207,8 @@ |
150 | 207 | time_tai--; |
151 | 208 | wall_to_monotonic.tv_sec--; |
152 | 209 | time_state = TIME_WAIT; |
153 | - printk(KERN_NOTICE "Clock: " | |
154 | - "deleting leap second 23:59:59 UTC\n"); | |
210 | + printk(KERN_NOTICE | |
211 | + "Clock: deleting leap second 23:59:59 UTC\n"); | |
155 | 212 | break; |
156 | 213 | case TIME_OOP: |
157 | 214 | time_tai++; |
... | ... | @@ -179,7 +236,7 @@ |
179 | 236 | */ |
180 | 237 | void second_overflow(void) |
181 | 238 | { |
182 | - s64 time_adj; | |
239 | + s64 delta; | |
183 | 240 | |
184 | 241 | /* Bump the maxerror field */ |
185 | 242 | time_maxerror += MAXFREQ / NSEC_PER_USEC; |
186 | 243 | |
187 | 244 | |
... | ... | @@ -192,24 +249,30 @@ |
192 | 249 | * Compute the phase adjustment for the next second. The offset is |
193 | 250 | * reduced by a fixed factor times the time constant. |
194 | 251 | */ |
195 | - tick_length = tick_length_base; | |
196 | - time_adj = shift_right(time_offset, SHIFT_PLL + time_constant); | |
197 | - time_offset -= time_adj; | |
198 | - tick_length += time_adj; | |
252 | + tick_length = tick_length_base; | |
199 | 253 | |
200 | - if (unlikely(time_adjust)) { | |
201 | - if (time_adjust > MAX_TICKADJ) { | |
202 | - time_adjust -= MAX_TICKADJ; | |
203 | - tick_length += MAX_TICKADJ_SCALED; | |
204 | - } else if (time_adjust < -MAX_TICKADJ) { | |
205 | - time_adjust += MAX_TICKADJ; | |
206 | - tick_length -= MAX_TICKADJ_SCALED; | |
207 | - } else { | |
208 | - tick_length += (s64)(time_adjust * NSEC_PER_USEC / | |
209 | - NTP_INTERVAL_FREQ) << NTP_SCALE_SHIFT; | |
210 | - time_adjust = 0; | |
211 | - } | |
254 | + delta = shift_right(time_offset, SHIFT_PLL + time_constant); | |
255 | + time_offset -= delta; | |
256 | + tick_length += delta; | |
257 | + | |
258 | + if (!time_adjust) | |
259 | + return; | |
260 | + | |
261 | + if (time_adjust > MAX_TICKADJ) { | |
262 | + time_adjust -= MAX_TICKADJ; | |
263 | + tick_length += MAX_TICKADJ_SCALED; | |
264 | + return; | |
212 | 265 | } |
266 | + | |
267 | + if (time_adjust < -MAX_TICKADJ) { | |
268 | + time_adjust += MAX_TICKADJ; | |
269 | + tick_length -= MAX_TICKADJ_SCALED; | |
270 | + return; | |
271 | + } | |
272 | + | |
273 | + tick_length += (s64)(time_adjust * NSEC_PER_USEC / NTP_INTERVAL_FREQ) | |
274 | + << NTP_SCALE_SHIFT; | |
275 | + time_adjust = 0; | |
213 | 276 | } |
214 | 277 | |
215 | 278 | #ifdef CONFIG_GENERIC_CMOS_UPDATE |
216 | 279 | |
... | ... | @@ -233,12 +296,13 @@ |
233 | 296 | * This code is run on a timer. If the clock is set, that timer |
234 | 297 | * may not expire at the correct time. Thus, we adjust... |
235 | 298 | */ |
236 | - if (!ntp_synced()) | |
299 | + if (!ntp_synced()) { | |
237 | 300 | /* |
238 | 301 | * Not synced, exit, do not restart a timer (if one is |
239 | 302 | * running, let it run out). |
240 | 303 | */ |
241 | 304 | return; |
305 | + } | |
242 | 306 | |
243 | 307 | getnstimeofday(&now); |
244 | 308 | if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) |
... | ... | @@ -270,7 +334,116 @@ |
270 | 334 | static inline void notify_cmos_timer(void) { } |
271 | 335 | #endif |
272 | 336 | |
273 | -/* adjtimex mainly allows reading (and writing, if superuser) of | |
337 | +/* | |
338 | + * Start the leap seconds timer: | |
339 | + */ | |
340 | +static inline void ntp_start_leap_timer(struct timespec *ts) | |
341 | +{ | |
342 | + long now = ts->tv_sec; | |
343 | + | |
344 | + if (time_status & STA_INS) { | |
345 | + time_state = TIME_INS; | |
346 | + now += 86400 - now % 86400; | |
347 | + hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS); | |
348 | + | |
349 | + return; | |
350 | + } | |
351 | + | |
352 | + if (time_status & STA_DEL) { | |
353 | + time_state = TIME_DEL; | |
354 | + now += 86400 - (now + 1) % 86400; | |
355 | + hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS); | |
356 | + } | |
357 | +} | |
358 | + | |
359 | +/* | |
360 | + * Propagate a new txc->status value into the NTP state: | |
361 | + */ | |
362 | +static inline void process_adj_status(struct timex *txc, struct timespec *ts) | |
363 | +{ | |
364 | + if ((time_status & STA_PLL) && !(txc->status & STA_PLL)) { | |
365 | + time_state = TIME_OK; | |
366 | + time_status = STA_UNSYNC; | |
367 | + } | |
368 | + | |
369 | + /* | |
370 | + * If we turn on PLL adjustments then reset the | |
371 | + * reference time to current time. | |
372 | + */ | |
373 | + if (!(time_status & STA_PLL) && (txc->status & STA_PLL)) | |
374 | + time_reftime = xtime.tv_sec; | |
375 | + | |
376 | + /* only set allowed bits */ | |
377 | + time_status &= STA_RONLY; | |
378 | + time_status |= txc->status & ~STA_RONLY; | |
379 | + | |
380 | + switch (time_state) { | |
381 | + case TIME_OK: | |
382 | + ntp_start_leap_timer(ts); | |
383 | + break; | |
384 | + case TIME_INS: | |
385 | + case TIME_DEL: | |
386 | + time_state = TIME_OK; | |
387 | + ntp_start_leap_timer(ts); | |
388 | + case TIME_WAIT: | |
389 | + if (!(time_status & (STA_INS | STA_DEL))) | |
390 | + time_state = TIME_OK; | |
391 | + break; | |
392 | + case TIME_OOP: | |
393 | + hrtimer_restart(&leap_timer); | |
394 | + break; | |
395 | + } | |
396 | +} | |
397 | +/* | |
398 | + * Called with the xtime lock held, so we can access and modify | |
399 | + * all the global NTP state: | |
400 | + */ | |
401 | +static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts) | |
402 | +{ | |
403 | + if (txc->modes & ADJ_STATUS) | |
404 | + process_adj_status(txc, ts); | |
405 | + | |
406 | + if (txc->modes & ADJ_NANO) | |
407 | + time_status |= STA_NANO; | |
408 | + | |
409 | + if (txc->modes & ADJ_MICRO) | |
410 | + time_status &= ~STA_NANO; | |
411 | + | |
412 | + if (txc->modes & ADJ_FREQUENCY) { | |
413 | + time_freq = txc->freq * PPM_SCALE; | |
414 | + time_freq = min(time_freq, MAXFREQ_SCALED); | |
415 | + time_freq = max(time_freq, -MAXFREQ_SCALED); | |
416 | + } | |
417 | + | |
418 | + if (txc->modes & ADJ_MAXERROR) | |
419 | + time_maxerror = txc->maxerror; | |
420 | + | |
421 | + if (txc->modes & ADJ_ESTERROR) | |
422 | + time_esterror = txc->esterror; | |
423 | + | |
424 | + if (txc->modes & ADJ_TIMECONST) { | |
425 | + time_constant = txc->constant; | |
426 | + if (!(time_status & STA_NANO)) | |
427 | + time_constant += 4; | |
428 | + time_constant = min(time_constant, (long)MAXTC); | |
429 | + time_constant = max(time_constant, 0l); | |
430 | + } | |
431 | + | |
432 | + if (txc->modes & ADJ_TAI && txc->constant > 0) | |
433 | + time_tai = txc->constant; | |
434 | + | |
435 | + if (txc->modes & ADJ_OFFSET) | |
436 | + ntp_update_offset(txc->offset); | |
437 | + | |
438 | + if (txc->modes & ADJ_TICK) | |
439 | + tick_usec = txc->tick; | |
440 | + | |
441 | + if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET)) | |
442 | + ntp_update_frequency(); | |
443 | +} | |
444 | + | |
445 | +/* | |
446 | + * adjtimex mainly allows reading (and writing, if superuser) of | |
274 | 447 | * kernel time-keeping variables. used by xntpd. |
275 | 448 | */ |
276 | 449 | int do_adjtimex(struct timex *txc) |
277 | 450 | |
... | ... | @@ -291,11 +464,14 @@ |
291 | 464 | if (txc->modes && !capable(CAP_SYS_TIME)) |
292 | 465 | return -EPERM; |
293 | 466 | |
294 | - /* if the quartz is off by more than 10% something is VERY wrong! */ | |
467 | + /* | |
468 | + * if the quartz is off by more than 10% then | |
469 | + * something is VERY wrong! | |
470 | + */ | |
295 | 471 | if (txc->modes & ADJ_TICK && |
296 | 472 | (txc->tick < 900000/USER_HZ || |
297 | 473 | txc->tick > 1100000/USER_HZ)) |
298 | - return -EINVAL; | |
474 | + return -EINVAL; | |
299 | 475 | |
300 | 476 | if (txc->modes & ADJ_STATUS && time_state != TIME_OK) |
301 | 477 | hrtimer_cancel(&leap_timer); |
... | ... | @@ -305,7 +481,6 @@ |
305 | 481 | |
306 | 482 | write_seqlock_irq(&xtime_lock); |
307 | 483 | |
308 | - /* If there are input parameters, then process them */ | |
309 | 484 | if (txc->modes & ADJ_ADJTIME) { |
310 | 485 | long save_adjust = time_adjust; |
311 | 486 | |
312 | 487 | |
313 | 488 | |
314 | 489 | |
315 | 490 | |
... | ... | @@ -315,98 +490,24 @@ |
315 | 490 | ntp_update_frequency(); |
316 | 491 | } |
317 | 492 | txc->offset = save_adjust; |
318 | - goto adj_done; | |
319 | - } | |
320 | - if (txc->modes) { | |
321 | - long sec; | |
493 | + } else { | |
322 | 494 | |
323 | - if (txc->modes & ADJ_STATUS) { | |
324 | - if ((time_status & STA_PLL) && | |
325 | - !(txc->status & STA_PLL)) { | |
326 | - time_state = TIME_OK; | |
327 | - time_status = STA_UNSYNC; | |
328 | - } | |
329 | - /* only set allowed bits */ | |
330 | - time_status &= STA_RONLY; | |
331 | - time_status |= txc->status & ~STA_RONLY; | |
495 | + /* If there are input parameters, then process them: */ | |
496 | + if (txc->modes) | |
497 | + process_adjtimex_modes(txc, &ts); | |
332 | 498 | |
333 | - switch (time_state) { | |
334 | - case TIME_OK: | |
335 | - start_timer: | |
336 | - sec = ts.tv_sec; | |
337 | - if (time_status & STA_INS) { | |
338 | - time_state = TIME_INS; | |
339 | - sec += 86400 - sec % 86400; | |
340 | - hrtimer_start(&leap_timer, ktime_set(sec, 0), HRTIMER_MODE_ABS); | |
341 | - } else if (time_status & STA_DEL) { | |
342 | - time_state = TIME_DEL; | |
343 | - sec += 86400 - (sec + 1) % 86400; | |
344 | - hrtimer_start(&leap_timer, ktime_set(sec, 0), HRTIMER_MODE_ABS); | |
345 | - } | |
346 | - break; | |
347 | - case TIME_INS: | |
348 | - case TIME_DEL: | |
349 | - time_state = TIME_OK; | |
350 | - goto start_timer; | |
351 | - break; | |
352 | - case TIME_WAIT: | |
353 | - if (!(time_status & (STA_INS | STA_DEL))) | |
354 | - time_state = TIME_OK; | |
355 | - break; | |
356 | - case TIME_OOP: | |
357 | - hrtimer_restart(&leap_timer); | |
358 | - break; | |
359 | - } | |
360 | - } | |
361 | - | |
362 | - if (txc->modes & ADJ_NANO) | |
363 | - time_status |= STA_NANO; | |
364 | - if (txc->modes & ADJ_MICRO) | |
365 | - time_status &= ~STA_NANO; | |
366 | - | |
367 | - if (txc->modes & ADJ_FREQUENCY) { | |
368 | - time_freq = (s64)txc->freq * PPM_SCALE; | |
369 | - time_freq = min(time_freq, MAXFREQ_SCALED); | |
370 | - time_freq = max(time_freq, -MAXFREQ_SCALED); | |
371 | - } | |
372 | - | |
373 | - if (txc->modes & ADJ_MAXERROR) | |
374 | - time_maxerror = txc->maxerror; | |
375 | - if (txc->modes & ADJ_ESTERROR) | |
376 | - time_esterror = txc->esterror; | |
377 | - | |
378 | - if (txc->modes & ADJ_TIMECONST) { | |
379 | - time_constant = txc->constant; | |
380 | - if (!(time_status & STA_NANO)) | |
381 | - time_constant += 4; | |
382 | - time_constant = min(time_constant, (long)MAXTC); | |
383 | - time_constant = max(time_constant, 0l); | |
384 | - } | |
385 | - | |
386 | - if (txc->modes & ADJ_TAI && txc->constant > 0) | |
387 | - time_tai = txc->constant; | |
388 | - | |
389 | - if (txc->modes & ADJ_OFFSET) | |
390 | - ntp_update_offset(txc->offset); | |
391 | - if (txc->modes & ADJ_TICK) | |
392 | - tick_usec = txc->tick; | |
393 | - | |
394 | - if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET)) | |
395 | - ntp_update_frequency(); | |
499 | + txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ, | |
500 | + NTP_SCALE_SHIFT); | |
501 | + if (!(time_status & STA_NANO)) | |
502 | + txc->offset /= NSEC_PER_USEC; | |
396 | 503 | } |
397 | 504 | |
398 | - txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ, | |
399 | - NTP_SCALE_SHIFT); | |
400 | - if (!(time_status & STA_NANO)) | |
401 | - txc->offset /= NSEC_PER_USEC; | |
402 | - | |
403 | -adj_done: | |
404 | 505 | result = time_state; /* mostly `TIME_OK' */ |
405 | 506 | if (time_status & (STA_UNSYNC|STA_CLOCKERR)) |
406 | 507 | result = TIME_ERROR; |
407 | 508 | |
408 | 509 | txc->freq = shift_right((time_freq >> PPM_SCALE_INV_SHIFT) * |
409 | - (s64)PPM_SCALE_INV, NTP_SCALE_SHIFT); | |
510 | + PPM_SCALE_INV, NTP_SCALE_SHIFT); | |
410 | 511 | txc->maxerror = time_maxerror; |
411 | 512 | txc->esterror = time_esterror; |
412 | 513 | txc->status = time_status; |
... | ... | @@ -425,6 +526,7 @@ |
425 | 526 | txc->calcnt = 0; |
426 | 527 | txc->errcnt = 0; |
427 | 528 | txc->stbcnt = 0; |
529 | + | |
428 | 530 | write_sequnlock_irq(&xtime_lock); |
429 | 531 | |
430 | 532 | txc->time.tv_sec = ts.tv_sec; |
... | ... | @@ -440,6 +542,8 @@ |
440 | 542 | static int __init ntp_tick_adj_setup(char *str) |
441 | 543 | { |
442 | 544 | ntp_tick_adj = simple_strtol(str, NULL, 0); |
545 | + ntp_tick_adj <<= NTP_SCALE_SHIFT; | |
546 | + | |
443 | 547 | return 1; |
444 | 548 | } |
445 | 549 |
kernel/timer.c
... | ... | @@ -589,12 +589,15 @@ |
589 | 589 | } |
590 | 590 | } |
591 | 591 | |
592 | -int __mod_timer(struct timer_list *timer, unsigned long expires) | |
592 | +static inline int | |
593 | +__mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) | |
593 | 594 | { |
594 | 595 | struct tvec_base *base, *new_base; |
595 | 596 | unsigned long flags; |
596 | - int ret = 0; | |
597 | + int ret; | |
597 | 598 | |
599 | + ret = 0; | |
600 | + | |
598 | 601 | timer_stats_timer_set_start_info(timer); |
599 | 602 | BUG_ON(!timer->function); |
600 | 603 | |
... | ... | @@ -603,6 +606,9 @@ |
603 | 606 | if (timer_pending(timer)) { |
604 | 607 | detach_timer(timer, 0); |
605 | 608 | ret = 1; |
609 | + } else { | |
610 | + if (pending_only) | |
611 | + goto out_unlock; | |
606 | 612 | } |
607 | 613 | |
608 | 614 | debug_timer_activate(timer); |
609 | 615 | |
610 | 616 | |
611 | 617 | |
612 | 618 | |
613 | 619 | |
614 | 620 | |
... | ... | @@ -629,42 +635,28 @@ |
629 | 635 | |
630 | 636 | timer->expires = expires; |
631 | 637 | internal_add_timer(base, timer); |
638 | + | |
639 | +out_unlock: | |
632 | 640 | spin_unlock_irqrestore(&base->lock, flags); |
633 | 641 | |
634 | 642 | return ret; |
635 | 643 | } |
636 | 644 | |
637 | -EXPORT_SYMBOL(__mod_timer); | |
638 | - | |
639 | 645 | /** |
640 | - * add_timer_on - start a timer on a particular CPU | |
641 | - * @timer: the timer to be added | |
642 | - * @cpu: the CPU to start it on | |
646 | + * mod_timer_pending - modify a pending timer's timeout | |
647 | + * @timer: the pending timer to be modified | |
648 | + * @expires: new timeout in jiffies | |
643 | 649 | * |
644 | - * This is not very scalable on SMP. Double adds are not possible. | |
650 | + * mod_timer_pending() is the same for pending timers as mod_timer(), | |
651 | + * but will not re-activate and modify already deleted timers. | |
652 | + * | |
653 | + * It is useful for unserialized use of timers. | |
645 | 654 | */ |
646 | -void add_timer_on(struct timer_list *timer, int cpu) | |
655 | +int mod_timer_pending(struct timer_list *timer, unsigned long expires) | |
647 | 656 | { |
648 | - struct tvec_base *base = per_cpu(tvec_bases, cpu); | |
649 | - unsigned long flags; | |
650 | - | |
651 | - timer_stats_timer_set_start_info(timer); | |
652 | - BUG_ON(timer_pending(timer) || !timer->function); | |
653 | - spin_lock_irqsave(&base->lock, flags); | |
654 | - timer_set_base(timer, base); | |
655 | - debug_timer_activate(timer); | |
656 | - internal_add_timer(base, timer); | |
657 | - /* | |
658 | - * Check whether the other CPU is idle and needs to be | |
659 | - * triggered to reevaluate the timer wheel when nohz is | |
660 | - * active. We are protected against the other CPU fiddling | |
661 | - * with the timer by holding the timer base lock. This also | |
662 | - * makes sure that a CPU on the way to idle can not evaluate | |
663 | - * the timer wheel. | |
664 | - */ | |
665 | - wake_up_idle_cpu(cpu); | |
666 | - spin_unlock_irqrestore(&base->lock, flags); | |
657 | + return __mod_timer(timer, expires, true); | |
667 | 658 | } |
659 | +EXPORT_SYMBOL(mod_timer_pending); | |
668 | 660 | |
669 | 661 | /** |
670 | 662 | * mod_timer - modify a timer's timeout |
... | ... | @@ -688,9 +680,6 @@ |
688 | 680 | */ |
689 | 681 | int mod_timer(struct timer_list *timer, unsigned long expires) |
690 | 682 | { |
691 | - BUG_ON(!timer->function); | |
692 | - | |
693 | - timer_stats_timer_set_start_info(timer); | |
694 | 683 | /* |
695 | 684 | * This is a common optimization triggered by the |
696 | 685 | * networking code - if the timer is re-modified |
697 | 686 | |
698 | 687 | |
... | ... | @@ -699,12 +688,62 @@ |
699 | 688 | if (timer->expires == expires && timer_pending(timer)) |
700 | 689 | return 1; |
701 | 690 | |
702 | - return __mod_timer(timer, expires); | |
691 | + return __mod_timer(timer, expires, false); | |
703 | 692 | } |
704 | - | |
705 | 693 | EXPORT_SYMBOL(mod_timer); |
706 | 694 | |
707 | 695 | /** |
696 | + * add_timer - start a timer | |
697 | + * @timer: the timer to be added | |
698 | + * | |
699 | + * The kernel will do a ->function(->data) callback from the | |
700 | + * timer interrupt at the ->expires point in the future. The | |
701 | + * current time is 'jiffies'. | |
702 | + * | |
703 | + * The timer's ->expires, ->function (and if the handler uses it, ->data) | |
704 | + * fields must be set prior calling this function. | |
705 | + * | |
706 | + * Timers with an ->expires field in the past will be executed in the next | |
707 | + * timer tick. | |
708 | + */ | |
709 | +void add_timer(struct timer_list *timer) | |
710 | +{ | |
711 | + BUG_ON(timer_pending(timer)); | |
712 | + mod_timer(timer, timer->expires); | |
713 | +} | |
714 | +EXPORT_SYMBOL(add_timer); | |
715 | + | |
716 | +/** | |
717 | + * add_timer_on - start a timer on a particular CPU | |
718 | + * @timer: the timer to be added | |
719 | + * @cpu: the CPU to start it on | |
720 | + * | |
721 | + * This is not very scalable on SMP. Double adds are not possible. | |
722 | + */ | |
723 | +void add_timer_on(struct timer_list *timer, int cpu) | |
724 | +{ | |
725 | + struct tvec_base *base = per_cpu(tvec_bases, cpu); | |
726 | + unsigned long flags; | |
727 | + | |
728 | + timer_stats_timer_set_start_info(timer); | |
729 | + BUG_ON(timer_pending(timer) || !timer->function); | |
730 | + spin_lock_irqsave(&base->lock, flags); | |
731 | + timer_set_base(timer, base); | |
732 | + debug_timer_activate(timer); | |
733 | + internal_add_timer(base, timer); | |
734 | + /* | |
735 | + * Check whether the other CPU is idle and needs to be | |
736 | + * triggered to reevaluate the timer wheel when nohz is | |
737 | + * active. We are protected against the other CPU fiddling | |
738 | + * with the timer by holding the timer base lock. This also | |
739 | + * makes sure that a CPU on the way to idle can not evaluate | |
740 | + * the timer wheel. | |
741 | + */ | |
742 | + wake_up_idle_cpu(cpu); | |
743 | + spin_unlock_irqrestore(&base->lock, flags); | |
744 | +} | |
745 | + | |
746 | +/** | |
708 | 747 | * del_timer - deactive a timer. |
709 | 748 | * @timer: the timer to be deactivated |
710 | 749 | * |
... | ... | @@ -733,7 +772,6 @@ |
733 | 772 | |
734 | 773 | return ret; |
735 | 774 | } |
736 | - | |
737 | 775 | EXPORT_SYMBOL(del_timer); |
738 | 776 | |
739 | 777 | #ifdef CONFIG_SMP |
... | ... | @@ -767,7 +805,6 @@ |
767 | 805 | |
768 | 806 | return ret; |
769 | 807 | } |
770 | - | |
771 | 808 | EXPORT_SYMBOL(try_to_del_timer_sync); |
772 | 809 | |
773 | 810 | /** |
... | ... | @@ -796,7 +833,6 @@ |
796 | 833 | cpu_relax(); |
797 | 834 | } |
798 | 835 | } |
799 | - | |
800 | 836 | EXPORT_SYMBOL(del_timer_sync); |
801 | 837 | #endif |
802 | 838 | |
... | ... | @@ -1268,7 +1304,7 @@ |
1268 | 1304 | expire = timeout + jiffies; |
1269 | 1305 | |
1270 | 1306 | setup_timer_on_stack(&timer, process_timeout, (unsigned long)current); |
1271 | - __mod_timer(&timer, expire); | |
1307 | + __mod_timer(&timer, expire, false); | |
1272 | 1308 | schedule(); |
1273 | 1309 | del_singleshot_timer_sync(&timer); |
1274 | 1310 |