diff options
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/Kconfig | 1 | ||||
-rw-r--r-- | kernel/time/clockevents.c | 15 | ||||
-rw-r--r-- | kernel/time/ntp.c | 95 | ||||
-rw-r--r-- | kernel/time/tick-broadcast.c | 112 | ||||
-rw-r--r-- | kernel/time/tick-common.c | 15 | ||||
-rw-r--r-- | kernel/time/tick-internal.h | 13 | ||||
-rw-r--r-- | kernel/time/tick-oneshot.c | 44 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 128 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 9 | ||||
-rw-r--r-- | kernel/time/timer_list.c | 20 |
10 files changed, 315 insertions, 137 deletions
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index 8d53106a0a92..95ed42951e0a 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig | |||
@@ -3,7 +3,6 @@ | |||
3 | # | 3 | # |
4 | config TICK_ONESHOT | 4 | config TICK_ONESHOT |
5 | bool | 5 | bool |
6 | default n | ||
7 | 6 | ||
8 | config NO_HZ | 7 | config NO_HZ |
9 | bool "Tickless System (Dynamic Ticks)" | 8 | bool "Tickless System (Dynamic Ticks)" |
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 3d1e3e1a1971..f8d968063cea 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -72,6 +72,16 @@ void clockevents_set_mode(struct clock_event_device *dev, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | /** | 74 | /** |
75 | * clockevents_shutdown - shutdown the device and clear next_event | ||
76 | * @dev: device to shutdown | ||
77 | */ | ||
78 | void clockevents_shutdown(struct clock_event_device *dev) | ||
79 | { | ||
80 | clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN); | ||
81 | dev->next_event.tv64 = KTIME_MAX; | ||
82 | } | ||
83 | |||
84 | /** | ||
75 | * clockevents_program_event - Reprogram the clock event device. | 85 | * clockevents_program_event - Reprogram the clock event device. |
76 | * @expires: absolute expiry time (monotonic clock) | 86 | * @expires: absolute expiry time (monotonic clock) |
77 | * | 87 | * |
@@ -177,7 +187,7 @@ void clockevents_register_device(struct clock_event_device *dev) | |||
177 | /* | 187 | /* |
178 | * Noop handler when we shut down an event device | 188 | * Noop handler when we shut down an event device |
179 | */ | 189 | */ |
180 | static void clockevents_handle_noop(struct clock_event_device *dev) | 190 | void clockevents_handle_noop(struct clock_event_device *dev) |
181 | { | 191 | { |
182 | } | 192 | } |
183 | 193 | ||
@@ -199,7 +209,6 @@ void clockevents_exchange_device(struct clock_event_device *old, | |||
199 | * released list and do a notify add later. | 209 | * released list and do a notify add later. |
200 | */ | 210 | */ |
201 | if (old) { | 211 | if (old) { |
202 | old->event_handler = clockevents_handle_noop; | ||
203 | clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED); | 212 | clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED); |
204 | list_del(&old->list); | 213 | list_del(&old->list); |
205 | list_add(&old->list, &clockevents_released); | 214 | list_add(&old->list, &clockevents_released); |
@@ -207,7 +216,7 @@ void clockevents_exchange_device(struct clock_event_device *old, | |||
207 | 216 | ||
208 | if (new) { | 217 | if (new) { |
209 | BUG_ON(new->mode != CLOCK_EVT_MODE_UNUSED); | 218 | BUG_ON(new->mode != CLOCK_EVT_MODE_UNUSED); |
210 | clockevents_set_mode(new, CLOCK_EVT_MODE_SHUTDOWN); | 219 | clockevents_shutdown(new); |
211 | } | 220 | } |
212 | local_irq_restore(flags); | 221 | local_irq_restore(flags); |
213 | } | 222 | } |
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 5125ddd8196b..1a20715bfd6e 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -10,13 +10,13 @@ | |||
10 | 10 | ||
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <linux/time.h> | 12 | #include <linux/time.h> |
13 | #include <linux/timer.h> | ||
14 | #include <linux/timex.h> | 13 | #include <linux/timex.h> |
15 | #include <linux/jiffies.h> | 14 | #include <linux/jiffies.h> |
16 | #include <linux/hrtimer.h> | 15 | #include <linux/hrtimer.h> |
17 | #include <linux/capability.h> | 16 | #include <linux/capability.h> |
18 | #include <linux/math64.h> | 17 | #include <linux/math64.h> |
19 | #include <linux/clocksource.h> | 18 | #include <linux/clocksource.h> |
19 | #include <linux/workqueue.h> | ||
20 | #include <asm/timex.h> | 20 | #include <asm/timex.h> |
21 | 21 | ||
22 | /* | 22 | /* |
@@ -218,11 +218,11 @@ void second_overflow(void) | |||
218 | /* Disable the cmos update - used by virtualization and embedded */ | 218 | /* Disable the cmos update - used by virtualization and embedded */ |
219 | int no_sync_cmos_clock __read_mostly; | 219 | int no_sync_cmos_clock __read_mostly; |
220 | 220 | ||
221 | static void sync_cmos_clock(unsigned long dummy); | 221 | static void sync_cmos_clock(struct work_struct *work); |
222 | 222 | ||
223 | static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0); | 223 | static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock); |
224 | 224 | ||
225 | static void sync_cmos_clock(unsigned long dummy) | 225 | static void sync_cmos_clock(struct work_struct *work) |
226 | { | 226 | { |
227 | struct timespec now, next; | 227 | struct timespec now, next; |
228 | int fail = 1; | 228 | int fail = 1; |
@@ -245,7 +245,7 @@ static void sync_cmos_clock(unsigned long dummy) | |||
245 | if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) | 245 | if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) |
246 | fail = update_persistent_clock(now); | 246 | fail = update_persistent_clock(now); |
247 | 247 | ||
248 | next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec; | 248 | next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2); |
249 | if (next.tv_nsec <= 0) | 249 | if (next.tv_nsec <= 0) |
250 | next.tv_nsec += NSEC_PER_SEC; | 250 | next.tv_nsec += NSEC_PER_SEC; |
251 | 251 | ||
@@ -258,13 +258,13 @@ static void sync_cmos_clock(unsigned long dummy) | |||
258 | next.tv_sec++; | 258 | next.tv_sec++; |
259 | next.tv_nsec -= NSEC_PER_SEC; | 259 | next.tv_nsec -= NSEC_PER_SEC; |
260 | } | 260 | } |
261 | mod_timer(&sync_cmos_timer, jiffies + timespec_to_jiffies(&next)); | 261 | schedule_delayed_work(&sync_cmos_work, timespec_to_jiffies(&next)); |
262 | } | 262 | } |
263 | 263 | ||
264 | static void notify_cmos_timer(void) | 264 | static void notify_cmos_timer(void) |
265 | { | 265 | { |
266 | if (!no_sync_cmos_clock) | 266 | if (!no_sync_cmos_clock) |
267 | mod_timer(&sync_cmos_timer, jiffies + 1); | 267 | schedule_delayed_work(&sync_cmos_work, 0); |
268 | } | 268 | } |
269 | 269 | ||
270 | #else | 270 | #else |
@@ -277,38 +277,50 @@ static inline void notify_cmos_timer(void) { } | |||
277 | int do_adjtimex(struct timex *txc) | 277 | int do_adjtimex(struct timex *txc) |
278 | { | 278 | { |
279 | struct timespec ts; | 279 | struct timespec ts; |
280 | long save_adjust, sec; | ||
281 | int result; | 280 | int result; |
282 | 281 | ||
283 | /* In order to modify anything, you gotta be super-user! */ | 282 | /* Validate the data before disabling interrupts */ |
284 | if (txc->modes && !capable(CAP_SYS_TIME)) | 283 | if (txc->modes & ADJ_ADJTIME) { |
285 | return -EPERM; | ||
286 | |||
287 | /* Now we validate the data before disabling interrupts */ | ||
288 | |||
289 | if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT) { | ||
290 | /* singleshot must not be used with any other mode bits */ | 284 | /* singleshot must not be used with any other mode bits */ |
291 | if (txc->modes & ~ADJ_OFFSET_SS_READ) | 285 | if (!(txc->modes & ADJ_OFFSET_SINGLESHOT)) |
292 | return -EINVAL; | 286 | return -EINVAL; |
287 | if (!(txc->modes & ADJ_OFFSET_READONLY) && | ||
288 | !capable(CAP_SYS_TIME)) | ||
289 | return -EPERM; | ||
290 | } else { | ||
291 | /* In order to modify anything, you gotta be super-user! */ | ||
292 | if (txc->modes && !capable(CAP_SYS_TIME)) | ||
293 | return -EPERM; | ||
294 | |||
295 | /* if the quartz is off by more than 10% something is VERY wrong! */ | ||
296 | if (txc->modes & ADJ_TICK && | ||
297 | (txc->tick < 900000/USER_HZ || | ||
298 | txc->tick > 1100000/USER_HZ)) | ||
299 | return -EINVAL; | ||
300 | |||
301 | if (txc->modes & ADJ_STATUS && time_state != TIME_OK) | ||
302 | hrtimer_cancel(&leap_timer); | ||
293 | } | 303 | } |
294 | 304 | ||
295 | /* if the quartz is off by more than 10% something is VERY wrong ! */ | ||
296 | if (txc->modes & ADJ_TICK) | ||
297 | if (txc->tick < 900000/USER_HZ || | ||
298 | txc->tick > 1100000/USER_HZ) | ||
299 | return -EINVAL; | ||
300 | |||
301 | if (time_state != TIME_OK && txc->modes & ADJ_STATUS) | ||
302 | hrtimer_cancel(&leap_timer); | ||
303 | getnstimeofday(&ts); | 305 | getnstimeofday(&ts); |
304 | 306 | ||
305 | write_seqlock_irq(&xtime_lock); | 307 | write_seqlock_irq(&xtime_lock); |
306 | 308 | ||
307 | /* Save for later - semantics of adjtime is to return old value */ | ||
308 | save_adjust = time_adjust; | ||
309 | |||
310 | /* If there are input parameters, then process them */ | 309 | /* If there are input parameters, then process them */ |
310 | if (txc->modes & ADJ_ADJTIME) { | ||
311 | long save_adjust = time_adjust; | ||
312 | |||
313 | if (!(txc->modes & ADJ_OFFSET_READONLY)) { | ||
314 | /* adjtime() is independent from ntp_adjtime() */ | ||
315 | time_adjust = txc->offset; | ||
316 | ntp_update_frequency(); | ||
317 | } | ||
318 | txc->offset = save_adjust; | ||
319 | goto adj_done; | ||
320 | } | ||
311 | if (txc->modes) { | 321 | if (txc->modes) { |
322 | long sec; | ||
323 | |||
312 | if (txc->modes & ADJ_STATUS) { | 324 | if (txc->modes & ADJ_STATUS) { |
313 | if ((time_status & STA_PLL) && | 325 | if ((time_status & STA_PLL) && |
314 | !(txc->status & STA_PLL)) { | 326 | !(txc->status & STA_PLL)) { |
@@ -375,13 +387,8 @@ int do_adjtimex(struct timex *txc) | |||
375 | if (txc->modes & ADJ_TAI && txc->constant > 0) | 387 | if (txc->modes & ADJ_TAI && txc->constant > 0) |
376 | time_tai = txc->constant; | 388 | time_tai = txc->constant; |
377 | 389 | ||
378 | if (txc->modes & ADJ_OFFSET) { | 390 | if (txc->modes & ADJ_OFFSET) |
379 | if (txc->modes == ADJ_OFFSET_SINGLESHOT) | 391 | ntp_update_offset(txc->offset); |
380 | /* adjtime() is independent from ntp_adjtime() */ | ||
381 | time_adjust = txc->offset; | ||
382 | else | ||
383 | ntp_update_offset(txc->offset); | ||
384 | } | ||
385 | if (txc->modes & ADJ_TICK) | 392 | if (txc->modes & ADJ_TICK) |
386 | tick_usec = txc->tick; | 393 | tick_usec = txc->tick; |
387 | 394 | ||
@@ -389,22 +396,18 @@ int do_adjtimex(struct timex *txc) | |||
389 | ntp_update_frequency(); | 396 | ntp_update_frequency(); |
390 | } | 397 | } |
391 | 398 | ||
399 | txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ, | ||
400 | NTP_SCALE_SHIFT); | ||
401 | if (!(time_status & STA_NANO)) | ||
402 | txc->offset /= NSEC_PER_USEC; | ||
403 | |||
404 | adj_done: | ||
392 | result = time_state; /* mostly `TIME_OK' */ | 405 | result = time_state; /* mostly `TIME_OK' */ |
393 | if (time_status & (STA_UNSYNC|STA_CLOCKERR)) | 406 | if (time_status & (STA_UNSYNC|STA_CLOCKERR)) |
394 | result = TIME_ERROR; | 407 | result = TIME_ERROR; |
395 | 408 | ||
396 | if ((txc->modes == ADJ_OFFSET_SINGLESHOT) || | 409 | txc->freq = shift_right((time_freq >> PPM_SCALE_INV_SHIFT) * |
397 | (txc->modes == ADJ_OFFSET_SS_READ)) | 410 | (s64)PPM_SCALE_INV, NTP_SCALE_SHIFT); |
398 | txc->offset = save_adjust; | ||
399 | else { | ||
400 | txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ, | ||
401 | NTP_SCALE_SHIFT); | ||
402 | if (!(time_status & STA_NANO)) | ||
403 | txc->offset /= NSEC_PER_USEC; | ||
404 | } | ||
405 | txc->freq = shift_right((s32)(time_freq >> PPM_SCALE_INV_SHIFT) * | ||
406 | (s64)PPM_SCALE_INV, | ||
407 | NTP_SCALE_SHIFT); | ||
408 | txc->maxerror = time_maxerror; | 411 | txc->maxerror = time_maxerror; |
409 | txc->esterror = time_esterror; | 412 | txc->esterror = time_esterror; |
410 | txc->status = time_status; | 413 | txc->status = time_status; |
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 31463d370b94..f98a1b7b16e9 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -175,6 +175,8 @@ static void tick_do_periodic_broadcast(void) | |||
175 | */ | 175 | */ |
176 | static void tick_handle_periodic_broadcast(struct clock_event_device *dev) | 176 | static void tick_handle_periodic_broadcast(struct clock_event_device *dev) |
177 | { | 177 | { |
178 | ktime_t next; | ||
179 | |||
178 | tick_do_periodic_broadcast(); | 180 | tick_do_periodic_broadcast(); |
179 | 181 | ||
180 | /* | 182 | /* |
@@ -185,10 +187,13 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev) | |||
185 | 187 | ||
186 | /* | 188 | /* |
187 | * Setup the next period for devices, which do not have | 189 | * Setup the next period for devices, which do not have |
188 | * periodic mode: | 190 | * periodic mode. We read dev->next_event first and add to it |
191 | * when the event alrady expired. clockevents_program_event() | ||
192 | * sets dev->next_event only when the event is really | ||
193 | * programmed to the device. | ||
189 | */ | 194 | */ |
190 | for (;;) { | 195 | for (next = dev->next_event; ;) { |
191 | ktime_t next = ktime_add(dev->next_event, tick_period); | 196 | next = ktime_add(next, tick_period); |
192 | 197 | ||
193 | if (!clockevents_program_event(dev, next, ktime_get())) | 198 | if (!clockevents_program_event(dev, next, ktime_get())) |
194 | return; | 199 | return; |
@@ -205,7 +210,7 @@ static void tick_do_broadcast_on_off(void *why) | |||
205 | struct clock_event_device *bc, *dev; | 210 | struct clock_event_device *bc, *dev; |
206 | struct tick_device *td; | 211 | struct tick_device *td; |
207 | unsigned long flags, *reason = why; | 212 | unsigned long flags, *reason = why; |
208 | int cpu; | 213 | int cpu, bc_stopped; |
209 | 214 | ||
210 | spin_lock_irqsave(&tick_broadcast_lock, flags); | 215 | spin_lock_irqsave(&tick_broadcast_lock, flags); |
211 | 216 | ||
@@ -223,14 +228,16 @@ static void tick_do_broadcast_on_off(void *why) | |||
223 | if (!tick_device_is_functional(dev)) | 228 | if (!tick_device_is_functional(dev)) |
224 | goto out; | 229 | goto out; |
225 | 230 | ||
231 | bc_stopped = cpus_empty(tick_broadcast_mask); | ||
232 | |||
226 | switch (*reason) { | 233 | switch (*reason) { |
227 | case CLOCK_EVT_NOTIFY_BROADCAST_ON: | 234 | case CLOCK_EVT_NOTIFY_BROADCAST_ON: |
228 | case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: | 235 | case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: |
229 | if (!cpu_isset(cpu, tick_broadcast_mask)) { | 236 | if (!cpu_isset(cpu, tick_broadcast_mask)) { |
230 | cpu_set(cpu, tick_broadcast_mask); | 237 | cpu_set(cpu, tick_broadcast_mask); |
231 | if (td->mode == TICKDEV_MODE_PERIODIC) | 238 | if (tick_broadcast_device.mode == |
232 | clockevents_set_mode(dev, | 239 | TICKDEV_MODE_PERIODIC) |
233 | CLOCK_EVT_MODE_SHUTDOWN); | 240 | clockevents_shutdown(dev); |
234 | } | 241 | } |
235 | if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE) | 242 | if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE) |
236 | tick_broadcast_force = 1; | 243 | tick_broadcast_force = 1; |
@@ -239,15 +246,17 @@ static void tick_do_broadcast_on_off(void *why) | |||
239 | if (!tick_broadcast_force && | 246 | if (!tick_broadcast_force && |
240 | cpu_isset(cpu, tick_broadcast_mask)) { | 247 | cpu_isset(cpu, tick_broadcast_mask)) { |
241 | cpu_clear(cpu, tick_broadcast_mask); | 248 | cpu_clear(cpu, tick_broadcast_mask); |
242 | if (td->mode == TICKDEV_MODE_PERIODIC) | 249 | if (tick_broadcast_device.mode == |
250 | TICKDEV_MODE_PERIODIC) | ||
243 | tick_setup_periodic(dev, 0); | 251 | tick_setup_periodic(dev, 0); |
244 | } | 252 | } |
245 | break; | 253 | break; |
246 | } | 254 | } |
247 | 255 | ||
248 | if (cpus_empty(tick_broadcast_mask)) | 256 | if (cpus_empty(tick_broadcast_mask)) { |
249 | clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); | 257 | if (!bc_stopped) |
250 | else { | 258 | clockevents_shutdown(bc); |
259 | } else if (bc_stopped) { | ||
251 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) | 260 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) |
252 | tick_broadcast_start_periodic(bc); | 261 | tick_broadcast_start_periodic(bc); |
253 | else | 262 | else |
@@ -298,7 +307,7 @@ void tick_shutdown_broadcast(unsigned int *cpup) | |||
298 | 307 | ||
299 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) { | 308 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) { |
300 | if (bc && cpus_empty(tick_broadcast_mask)) | 309 | if (bc && cpus_empty(tick_broadcast_mask)) |
301 | clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); | 310 | clockevents_shutdown(bc); |
302 | } | 311 | } |
303 | 312 | ||
304 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 313 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
@@ -313,7 +322,7 @@ void tick_suspend_broadcast(void) | |||
313 | 322 | ||
314 | bc = tick_broadcast_device.evtdev; | 323 | bc = tick_broadcast_device.evtdev; |
315 | if (bc) | 324 | if (bc) |
316 | clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); | 325 | clockevents_shutdown(bc); |
317 | 326 | ||
318 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 327 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
319 | } | 328 | } |
@@ -364,16 +373,8 @@ cpumask_t *tick_get_broadcast_oneshot_mask(void) | |||
364 | static int tick_broadcast_set_event(ktime_t expires, int force) | 373 | static int tick_broadcast_set_event(ktime_t expires, int force) |
365 | { | 374 | { |
366 | struct clock_event_device *bc = tick_broadcast_device.evtdev; | 375 | struct clock_event_device *bc = tick_broadcast_device.evtdev; |
367 | ktime_t now = ktime_get(); | 376 | |
368 | int res; | 377 | return tick_dev_program_event(bc, expires, force); |
369 | |||
370 | for(;;) { | ||
371 | res = clockevents_program_event(bc, expires, now); | ||
372 | if (!res || !force) | ||
373 | return res; | ||
374 | now = ktime_get(); | ||
375 | expires = ktime_add(now, ktime_set(0, bc->min_delta_ns)); | ||
376 | } | ||
377 | } | 378 | } |
378 | 379 | ||
379 | int tick_resume_broadcast_oneshot(struct clock_event_device *bc) | 380 | int tick_resume_broadcast_oneshot(struct clock_event_device *bc) |
@@ -383,6 +384,19 @@ int tick_resume_broadcast_oneshot(struct clock_event_device *bc) | |||
383 | } | 384 | } |
384 | 385 | ||
385 | /* | 386 | /* |
387 | * Called from irq_enter() when idle was interrupted to reenable the | ||
388 | * per cpu device. | ||
389 | */ | ||
390 | void tick_check_oneshot_broadcast(int cpu) | ||
391 | { | ||
392 | if (cpu_isset(cpu, tick_broadcast_oneshot_mask)) { | ||
393 | struct tick_device *td = &per_cpu(tick_cpu_device, cpu); | ||
394 | |||
395 | clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_ONESHOT); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | /* | ||
386 | * Handle oneshot mode broadcasting | 400 | * Handle oneshot mode broadcasting |
387 | */ | 401 | */ |
388 | static void tick_handle_oneshot_broadcast(struct clock_event_device *dev) | 402 | static void tick_handle_oneshot_broadcast(struct clock_event_device *dev) |
@@ -491,14 +505,52 @@ static void tick_broadcast_clear_oneshot(int cpu) | |||
491 | cpu_clear(cpu, tick_broadcast_oneshot_mask); | 505 | cpu_clear(cpu, tick_broadcast_oneshot_mask); |
492 | } | 506 | } |
493 | 507 | ||
508 | static void tick_broadcast_init_next_event(cpumask_t *mask, ktime_t expires) | ||
509 | { | ||
510 | struct tick_device *td; | ||
511 | int cpu; | ||
512 | |||
513 | for_each_cpu_mask_nr(cpu, *mask) { | ||
514 | td = &per_cpu(tick_cpu_device, cpu); | ||
515 | if (td->evtdev) | ||
516 | td->evtdev->next_event = expires; | ||
517 | } | ||
518 | } | ||
519 | |||
494 | /** | 520 | /** |
495 | * tick_broadcast_setup_oneshot - setup the broadcast device | 521 | * tick_broadcast_setup_oneshot - setup the broadcast device |
496 | */ | 522 | */ |
497 | void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | 523 | void tick_broadcast_setup_oneshot(struct clock_event_device *bc) |
498 | { | 524 | { |
499 | bc->event_handler = tick_handle_oneshot_broadcast; | 525 | /* Set it up only once ! */ |
500 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); | 526 | if (bc->event_handler != tick_handle_oneshot_broadcast) { |
501 | bc->next_event.tv64 = KTIME_MAX; | 527 | int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC; |
528 | int cpu = smp_processor_id(); | ||
529 | cpumask_t mask; | ||
530 | |||
531 | bc->event_handler = tick_handle_oneshot_broadcast; | ||
532 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); | ||
533 | |||
534 | /* Take the do_timer update */ | ||
535 | tick_do_timer_cpu = cpu; | ||
536 | |||
537 | /* | ||
538 | * We must be careful here. There might be other CPUs | ||
539 | * waiting for periodic broadcast. We need to set the | ||
540 | * oneshot_mask bits for those and program the | ||
541 | * broadcast device to fire. | ||
542 | */ | ||
543 | mask = tick_broadcast_mask; | ||
544 | cpu_clear(cpu, mask); | ||
545 | cpus_or(tick_broadcast_oneshot_mask, | ||
546 | tick_broadcast_oneshot_mask, mask); | ||
547 | |||
548 | if (was_periodic && !cpus_empty(mask)) { | ||
549 | tick_broadcast_init_next_event(&mask, tick_next_period); | ||
550 | tick_broadcast_set_event(tick_next_period, 1); | ||
551 | } else | ||
552 | bc->next_event.tv64 = KTIME_MAX; | ||
553 | } | ||
502 | } | 554 | } |
503 | 555 | ||
504 | /* | 556 | /* |
@@ -538,4 +590,12 @@ void tick_shutdown_broadcast_oneshot(unsigned int *cpup) | |||
538 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 590 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
539 | } | 591 | } |
540 | 592 | ||
593 | /* | ||
594 | * Check, whether the broadcast device is in one shot mode | ||
595 | */ | ||
596 | int tick_broadcast_oneshot_active(void) | ||
597 | { | ||
598 | return tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT; | ||
599 | } | ||
600 | |||
541 | #endif | 601 | #endif |
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 80c4336f4188..df12434b43ca 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c | |||
@@ -33,7 +33,7 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device); | |||
33 | */ | 33 | */ |
34 | ktime_t tick_next_period; | 34 | ktime_t tick_next_period; |
35 | ktime_t tick_period; | 35 | ktime_t tick_period; |
36 | int tick_do_timer_cpu __read_mostly = -1; | 36 | int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT; |
37 | DEFINE_SPINLOCK(tick_device_lock); | 37 | DEFINE_SPINLOCK(tick_device_lock); |
38 | 38 | ||
39 | /* | 39 | /* |
@@ -109,7 +109,8 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast) | |||
109 | if (!tick_device_is_functional(dev)) | 109 | if (!tick_device_is_functional(dev)) |
110 | return; | 110 | return; |
111 | 111 | ||
112 | if (dev->features & CLOCK_EVT_FEAT_PERIODIC) { | 112 | if ((dev->features & CLOCK_EVT_FEAT_PERIODIC) && |
113 | !tick_broadcast_oneshot_active()) { | ||
113 | clockevents_set_mode(dev, CLOCK_EVT_MODE_PERIODIC); | 114 | clockevents_set_mode(dev, CLOCK_EVT_MODE_PERIODIC); |
114 | } else { | 115 | } else { |
115 | unsigned long seq; | 116 | unsigned long seq; |
@@ -148,7 +149,7 @@ static void tick_setup_device(struct tick_device *td, | |||
148 | * If no cpu took the do_timer update, assign it to | 149 | * If no cpu took the do_timer update, assign it to |
149 | * this cpu: | 150 | * this cpu: |
150 | */ | 151 | */ |
151 | if (tick_do_timer_cpu == -1) { | 152 | if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) { |
152 | tick_do_timer_cpu = cpu; | 153 | tick_do_timer_cpu = cpu; |
153 | tick_next_period = ktime_get(); | 154 | tick_next_period = ktime_get(); |
154 | tick_period = ktime_set(0, NSEC_PER_SEC / HZ); | 155 | tick_period = ktime_set(0, NSEC_PER_SEC / HZ); |
@@ -161,6 +162,7 @@ static void tick_setup_device(struct tick_device *td, | |||
161 | } else { | 162 | } else { |
162 | handler = td->evtdev->event_handler; | 163 | handler = td->evtdev->event_handler; |
163 | next_event = td->evtdev->next_event; | 164 | next_event = td->evtdev->next_event; |
165 | td->evtdev->event_handler = clockevents_handle_noop; | ||
164 | } | 166 | } |
165 | 167 | ||
166 | td->evtdev = newdev; | 168 | td->evtdev = newdev; |
@@ -248,7 +250,7 @@ static int tick_check_new_device(struct clock_event_device *newdev) | |||
248 | * not give it back to the clockevents layer ! | 250 | * not give it back to the clockevents layer ! |
249 | */ | 251 | */ |
250 | if (tick_is_broadcast_device(curdev)) { | 252 | if (tick_is_broadcast_device(curdev)) { |
251 | clockevents_set_mode(curdev, CLOCK_EVT_MODE_SHUTDOWN); | 253 | clockevents_shutdown(curdev); |
252 | curdev = NULL; | 254 | curdev = NULL; |
253 | } | 255 | } |
254 | clockevents_exchange_device(curdev, newdev); | 256 | clockevents_exchange_device(curdev, newdev); |
@@ -299,7 +301,8 @@ static void tick_shutdown(unsigned int *cpup) | |||
299 | if (*cpup == tick_do_timer_cpu) { | 301 | if (*cpup == tick_do_timer_cpu) { |
300 | int cpu = first_cpu(cpu_online_map); | 302 | int cpu = first_cpu(cpu_online_map); |
301 | 303 | ||
302 | tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : -1; | 304 | tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : |
305 | TICK_DO_TIMER_NONE; | ||
303 | } | 306 | } |
304 | spin_unlock_irqrestore(&tick_device_lock, flags); | 307 | spin_unlock_irqrestore(&tick_device_lock, flags); |
305 | } | 308 | } |
@@ -310,7 +313,7 @@ static void tick_suspend(void) | |||
310 | unsigned long flags; | 313 | unsigned long flags; |
311 | 314 | ||
312 | spin_lock_irqsave(&tick_device_lock, flags); | 315 | spin_lock_irqsave(&tick_device_lock, flags); |
313 | clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN); | 316 | clockevents_shutdown(td->evtdev); |
314 | spin_unlock_irqrestore(&tick_device_lock, flags); | 317 | spin_unlock_irqrestore(&tick_device_lock, flags); |
315 | } | 318 | } |
316 | 319 | ||
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index f13f2b7f4fd4..b1c05bf75ee0 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h | |||
@@ -1,6 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * tick internal variable and functions used by low/high res code | 2 | * tick internal variable and functions used by low/high res code |
3 | */ | 3 | */ |
4 | |||
5 | #define TICK_DO_TIMER_NONE -1 | ||
6 | #define TICK_DO_TIMER_BOOT -2 | ||
7 | |||
4 | DECLARE_PER_CPU(struct tick_device, tick_cpu_device); | 8 | DECLARE_PER_CPU(struct tick_device, tick_cpu_device); |
5 | extern spinlock_t tick_device_lock; | 9 | extern spinlock_t tick_device_lock; |
6 | extern ktime_t tick_next_period; | 10 | extern ktime_t tick_next_period; |
@@ -10,6 +14,8 @@ extern int tick_do_timer_cpu __read_mostly; | |||
10 | extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast); | 14 | extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast); |
11 | extern void tick_handle_periodic(struct clock_event_device *dev); | 15 | extern void tick_handle_periodic(struct clock_event_device *dev); |
12 | 16 | ||
17 | extern void clockevents_shutdown(struct clock_event_device *dev); | ||
18 | |||
13 | /* | 19 | /* |
14 | * NO_HZ / high resolution timer shared code | 20 | * NO_HZ / high resolution timer shared code |
15 | */ | 21 | */ |
@@ -17,6 +23,8 @@ extern void tick_handle_periodic(struct clock_event_device *dev); | |||
17 | extern void tick_setup_oneshot(struct clock_event_device *newdev, | 23 | extern void tick_setup_oneshot(struct clock_event_device *newdev, |
18 | void (*handler)(struct clock_event_device *), | 24 | void (*handler)(struct clock_event_device *), |
19 | ktime_t nextevt); | 25 | ktime_t nextevt); |
26 | extern int tick_dev_program_event(struct clock_event_device *dev, | ||
27 | ktime_t expires, int force); | ||
20 | extern int tick_program_event(ktime_t expires, int force); | 28 | extern int tick_program_event(ktime_t expires, int force); |
21 | extern void tick_oneshot_notify(void); | 29 | extern void tick_oneshot_notify(void); |
22 | extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *)); | 30 | extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *)); |
@@ -27,6 +35,8 @@ extern void tick_broadcast_oneshot_control(unsigned long reason); | |||
27 | extern void tick_broadcast_switch_to_oneshot(void); | 35 | extern void tick_broadcast_switch_to_oneshot(void); |
28 | extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup); | 36 | extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup); |
29 | extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc); | 37 | extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc); |
38 | extern int tick_broadcast_oneshot_active(void); | ||
39 | extern void tick_check_oneshot_broadcast(int cpu); | ||
30 | # else /* BROADCAST */ | 40 | # else /* BROADCAST */ |
31 | static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | 41 | static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) |
32 | { | 42 | { |
@@ -35,6 +45,8 @@ static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | |||
35 | static inline void tick_broadcast_oneshot_control(unsigned long reason) { } | 45 | static inline void tick_broadcast_oneshot_control(unsigned long reason) { } |
36 | static inline void tick_broadcast_switch_to_oneshot(void) { } | 46 | static inline void tick_broadcast_switch_to_oneshot(void) { } |
37 | static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } | 47 | static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } |
48 | static inline int tick_broadcast_oneshot_active(void) { return 0; } | ||
49 | static inline void tick_check_oneshot_broadcast(int cpu) { } | ||
38 | # endif /* !BROADCAST */ | 50 | # endif /* !BROADCAST */ |
39 | 51 | ||
40 | #else /* !ONESHOT */ | 52 | #else /* !ONESHOT */ |
@@ -64,6 +76,7 @@ static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc) | |||
64 | { | 76 | { |
65 | return 0; | 77 | return 0; |
66 | } | 78 | } |
79 | static inline int tick_broadcast_oneshot_active(void) { return 0; } | ||
67 | #endif /* !TICK_ONESHOT */ | 80 | #endif /* !TICK_ONESHOT */ |
68 | 81 | ||
69 | /* | 82 | /* |
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c index 450c04935b66..2e8de678e767 100644 --- a/kernel/time/tick-oneshot.c +++ b/kernel/time/tick-oneshot.c | |||
@@ -23,24 +23,56 @@ | |||
23 | #include "tick-internal.h" | 23 | #include "tick-internal.h" |
24 | 24 | ||
25 | /** | 25 | /** |
26 | * tick_program_event | 26 | * tick_program_event internal worker function |
27 | */ | 27 | */ |
28 | int tick_program_event(ktime_t expires, int force) | 28 | int tick_dev_program_event(struct clock_event_device *dev, ktime_t expires, |
29 | int force) | ||
29 | { | 30 | { |
30 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; | ||
31 | ktime_t now = ktime_get(); | 31 | ktime_t now = ktime_get(); |
32 | int i; | ||
32 | 33 | ||
33 | while (1) { | 34 | for (i = 0;;) { |
34 | int ret = clockevents_program_event(dev, expires, now); | 35 | int ret = clockevents_program_event(dev, expires, now); |
35 | 36 | ||
36 | if (!ret || !force) | 37 | if (!ret || !force) |
37 | return ret; | 38 | return ret; |
39 | |||
40 | /* | ||
41 | * We tried 2 times to program the device with the given | ||
42 | * min_delta_ns. If that's not working then we double it | ||
43 | * and emit a warning. | ||
44 | */ | ||
45 | if (++i > 2) { | ||
46 | /* Increase the min. delta and try again */ | ||
47 | if (!dev->min_delta_ns) | ||
48 | dev->min_delta_ns = 5000; | ||
49 | else | ||
50 | dev->min_delta_ns += dev->min_delta_ns >> 1; | ||
51 | |||
52 | printk(KERN_WARNING | ||
53 | "CE: %s increasing min_delta_ns to %lu nsec\n", | ||
54 | dev->name ? dev->name : "?", | ||
55 | dev->min_delta_ns << 1); | ||
56 | |||
57 | i = 0; | ||
58 | } | ||
59 | |||
38 | now = ktime_get(); | 60 | now = ktime_get(); |
39 | expires = ktime_add(now, ktime_set(0, dev->min_delta_ns)); | 61 | expires = ktime_add_ns(now, dev->min_delta_ns); |
40 | } | 62 | } |
41 | } | 63 | } |
42 | 64 | ||
43 | /** | 65 | /** |
66 | * tick_program_event | ||
67 | */ | ||
68 | int tick_program_event(ktime_t expires, int force) | ||
69 | { | ||
70 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; | ||
71 | |||
72 | return tick_dev_program_event(dev, expires, force); | ||
73 | } | ||
74 | |||
75 | /** | ||
44 | * tick_resume_onshot - resume oneshot mode | 76 | * tick_resume_onshot - resume oneshot mode |
45 | */ | 77 | */ |
46 | void tick_resume_oneshot(void) | 78 | void tick_resume_oneshot(void) |
@@ -61,7 +93,7 @@ void tick_setup_oneshot(struct clock_event_device *newdev, | |||
61 | { | 93 | { |
62 | newdev->event_handler = handler; | 94 | newdev->event_handler = handler; |
63 | clockevents_set_mode(newdev, CLOCK_EVT_MODE_ONESHOT); | 95 | clockevents_set_mode(newdev, CLOCK_EVT_MODE_ONESHOT); |
64 | clockevents_program_event(newdev, next_event, ktime_get()); | 96 | tick_dev_program_event(newdev, next_event, 1); |
65 | } | 97 | } |
66 | 98 | ||
67 | /** | 99 | /** |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index f5da526424a9..0581c11fe6c6 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/profile.h> | 20 | #include <linux/profile.h> |
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/tick.h> | 22 | #include <linux/tick.h> |
23 | #include <linux/module.h> | ||
23 | 24 | ||
24 | #include <asm/irq_regs.h> | 25 | #include <asm/irq_regs.h> |
25 | 26 | ||
@@ -75,6 +76,9 @@ static void tick_do_update_jiffies64(ktime_t now) | |||
75 | incr * ticks); | 76 | incr * ticks); |
76 | } | 77 | } |
77 | do_timer(++ticks); | 78 | do_timer(++ticks); |
79 | |||
80 | /* Keep the tick_next_period variable up to date */ | ||
81 | tick_next_period = ktime_add(last_jiffies_update, tick_period); | ||
78 | } | 82 | } |
79 | write_sequnlock(&xtime_lock); | 83 | write_sequnlock(&xtime_lock); |
80 | } | 84 | } |
@@ -151,7 +155,7 @@ void tick_nohz_update_jiffies(void) | |||
151 | touch_softlockup_watchdog(); | 155 | touch_softlockup_watchdog(); |
152 | } | 156 | } |
153 | 157 | ||
154 | void tick_nohz_stop_idle(int cpu) | 158 | static void tick_nohz_stop_idle(int cpu) |
155 | { | 159 | { |
156 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | 160 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); |
157 | 161 | ||
@@ -162,6 +166,8 @@ void tick_nohz_stop_idle(int cpu) | |||
162 | ts->idle_lastupdate = now; | 166 | ts->idle_lastupdate = now; |
163 | ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta); | 167 | ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta); |
164 | ts->idle_active = 0; | 168 | ts->idle_active = 0; |
169 | |||
170 | sched_clock_idle_wakeup_event(0); | ||
165 | } | 171 | } |
166 | } | 172 | } |
167 | 173 | ||
@@ -177,6 +183,7 @@ static ktime_t tick_nohz_start_idle(struct tick_sched *ts) | |||
177 | } | 183 | } |
178 | ts->idle_entrytime = now; | 184 | ts->idle_entrytime = now; |
179 | ts->idle_active = 1; | 185 | ts->idle_active = 1; |
186 | sched_clock_idle_sleep_event(); | ||
180 | return now; | 187 | return now; |
181 | } | 188 | } |
182 | 189 | ||
@@ -184,9 +191,17 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) | |||
184 | { | 191 | { |
185 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | 192 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); |
186 | 193 | ||
187 | *last_update_time = ktime_to_us(ts->idle_lastupdate); | 194 | if (!tick_nohz_enabled) |
195 | return -1; | ||
196 | |||
197 | if (ts->idle_active) | ||
198 | *last_update_time = ktime_to_us(ts->idle_lastupdate); | ||
199 | else | ||
200 | *last_update_time = ktime_to_us(ktime_get()); | ||
201 | |||
188 | return ktime_to_us(ts->idle_sleeptime); | 202 | return ktime_to_us(ts->idle_sleeptime); |
189 | } | 203 | } |
204 | EXPORT_SYMBOL_GPL(get_cpu_idle_time_us); | ||
190 | 205 | ||
191 | /** | 206 | /** |
192 | * tick_nohz_stop_sched_tick - stop the idle tick from the idle task | 207 | * tick_nohz_stop_sched_tick - stop the idle tick from the idle task |
@@ -218,7 +233,7 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
218 | */ | 233 | */ |
219 | if (unlikely(!cpu_online(cpu))) { | 234 | if (unlikely(!cpu_online(cpu))) { |
220 | if (cpu == tick_do_timer_cpu) | 235 | if (cpu == tick_do_timer_cpu) |
221 | tick_do_timer_cpu = -1; | 236 | tick_do_timer_cpu = TICK_DO_TIMER_NONE; |
222 | } | 237 | } |
223 | 238 | ||
224 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) | 239 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) |
@@ -255,7 +270,7 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
255 | next_jiffies = get_next_timer_interrupt(last_jiffies); | 270 | next_jiffies = get_next_timer_interrupt(last_jiffies); |
256 | delta_jiffies = next_jiffies - last_jiffies; | 271 | delta_jiffies = next_jiffies - last_jiffies; |
257 | 272 | ||
258 | if (rcu_needs_cpu(cpu)) | 273 | if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu)) |
259 | delta_jiffies = 1; | 274 | delta_jiffies = 1; |
260 | /* | 275 | /* |
261 | * Do not stop the tick, if we are only one off | 276 | * Do not stop the tick, if we are only one off |
@@ -300,7 +315,7 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
300 | * invoked. | 315 | * invoked. |
301 | */ | 316 | */ |
302 | if (cpu == tick_do_timer_cpu) | 317 | if (cpu == tick_do_timer_cpu) |
303 | tick_do_timer_cpu = -1; | 318 | tick_do_timer_cpu = TICK_DO_TIMER_NONE; |
304 | 319 | ||
305 | ts->idle_sleeps++; | 320 | ts->idle_sleeps++; |
306 | 321 | ||
@@ -362,6 +377,32 @@ ktime_t tick_nohz_get_sleep_length(void) | |||
362 | return ts->sleep_length; | 377 | return ts->sleep_length; |
363 | } | 378 | } |
364 | 379 | ||
380 | static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) | ||
381 | { | ||
382 | hrtimer_cancel(&ts->sched_timer); | ||
383 | ts->sched_timer.expires = ts->idle_tick; | ||
384 | |||
385 | while (1) { | ||
386 | /* Forward the time to expire in the future */ | ||
387 | hrtimer_forward(&ts->sched_timer, now, tick_period); | ||
388 | |||
389 | if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { | ||
390 | hrtimer_start(&ts->sched_timer, | ||
391 | ts->sched_timer.expires, | ||
392 | HRTIMER_MODE_ABS); | ||
393 | /* Check, if the timer was already in the past */ | ||
394 | if (hrtimer_active(&ts->sched_timer)) | ||
395 | break; | ||
396 | } else { | ||
397 | if (!tick_program_event(ts->sched_timer.expires, 0)) | ||
398 | break; | ||
399 | } | ||
400 | /* Update jiffies and reread time */ | ||
401 | tick_do_update_jiffies64(now); | ||
402 | now = ktime_get(); | ||
403 | } | ||
404 | } | ||
405 | |||
365 | /** | 406 | /** |
366 | * tick_nohz_restart_sched_tick - restart the idle tick from the idle task | 407 | * tick_nohz_restart_sched_tick - restart the idle tick from the idle task |
367 | * | 408 | * |
@@ -415,28 +456,7 @@ void tick_nohz_restart_sched_tick(void) | |||
415 | */ | 456 | */ |
416 | ts->tick_stopped = 0; | 457 | ts->tick_stopped = 0; |
417 | ts->idle_exittime = now; | 458 | ts->idle_exittime = now; |
418 | hrtimer_cancel(&ts->sched_timer); | 459 | tick_nohz_restart(ts, now); |
419 | ts->sched_timer.expires = ts->idle_tick; | ||
420 | |||
421 | while (1) { | ||
422 | /* Forward the time to expire in the future */ | ||
423 | hrtimer_forward(&ts->sched_timer, now, tick_period); | ||
424 | |||
425 | if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { | ||
426 | hrtimer_start(&ts->sched_timer, | ||
427 | ts->sched_timer.expires, | ||
428 | HRTIMER_MODE_ABS); | ||
429 | /* Check, if the timer was already in the past */ | ||
430 | if (hrtimer_active(&ts->sched_timer)) | ||
431 | break; | ||
432 | } else { | ||
433 | if (!tick_program_event(ts->sched_timer.expires, 0)) | ||
434 | break; | ||
435 | } | ||
436 | /* Update jiffies and reread time */ | ||
437 | tick_do_update_jiffies64(now); | ||
438 | now = ktime_get(); | ||
439 | } | ||
440 | local_irq_enable(); | 460 | local_irq_enable(); |
441 | } | 461 | } |
442 | 462 | ||
@@ -465,7 +485,7 @@ static void tick_nohz_handler(struct clock_event_device *dev) | |||
465 | * this duty, then the jiffies update is still serialized by | 485 | * this duty, then the jiffies update is still serialized by |
466 | * xtime_lock. | 486 | * xtime_lock. |
467 | */ | 487 | */ |
468 | if (unlikely(tick_do_timer_cpu == -1)) | 488 | if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) |
469 | tick_do_timer_cpu = cpu; | 489 | tick_do_timer_cpu = cpu; |
470 | 490 | ||
471 | /* Check, if the jiffies need an update */ | 491 | /* Check, if the jiffies need an update */ |
@@ -488,10 +508,6 @@ static void tick_nohz_handler(struct clock_event_device *dev) | |||
488 | update_process_times(user_mode(regs)); | 508 | update_process_times(user_mode(regs)); |
489 | profile_tick(CPU_PROFILING); | 509 | profile_tick(CPU_PROFILING); |
490 | 510 | ||
491 | /* Do not restart, when we are in the idle loop */ | ||
492 | if (ts->tick_stopped) | ||
493 | return; | ||
494 | |||
495 | while (tick_nohz_reprogram(ts, now)) { | 511 | while (tick_nohz_reprogram(ts, now)) { |
496 | now = ktime_get(); | 512 | now = ktime_get(); |
497 | tick_do_update_jiffies64(now); | 513 | tick_do_update_jiffies64(now); |
@@ -537,6 +553,27 @@ static void tick_nohz_switch_to_nohz(void) | |||
537 | smp_processor_id()); | 553 | smp_processor_id()); |
538 | } | 554 | } |
539 | 555 | ||
556 | /* | ||
557 | * When NOHZ is enabled and the tick is stopped, we need to kick the | ||
558 | * tick timer from irq_enter() so that the jiffies update is kept | ||
559 | * alive during long running softirqs. That's ugly as hell, but | ||
560 | * correctness is key even if we need to fix the offending softirq in | ||
561 | * the first place. | ||
562 | * | ||
563 | * Note, this is different to tick_nohz_restart. We just kick the | ||
564 | * timer and do not touch the other magic bits which need to be done | ||
565 | * when idle is left. | ||
566 | */ | ||
567 | static void tick_nohz_kick_tick(int cpu) | ||
568 | { | ||
569 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | ||
570 | |||
571 | if (!ts->tick_stopped) | ||
572 | return; | ||
573 | |||
574 | tick_nohz_restart(ts, ktime_get()); | ||
575 | } | ||
576 | |||
540 | #else | 577 | #else |
541 | 578 | ||
542 | static inline void tick_nohz_switch_to_nohz(void) { } | 579 | static inline void tick_nohz_switch_to_nohz(void) { } |
@@ -544,6 +581,19 @@ static inline void tick_nohz_switch_to_nohz(void) { } | |||
544 | #endif /* NO_HZ */ | 581 | #endif /* NO_HZ */ |
545 | 582 | ||
546 | /* | 583 | /* |
584 | * Called from irq_enter to notify about the possible interruption of idle() | ||
585 | */ | ||
586 | void tick_check_idle(int cpu) | ||
587 | { | ||
588 | tick_check_oneshot_broadcast(cpu); | ||
589 | #ifdef CONFIG_NO_HZ | ||
590 | tick_nohz_stop_idle(cpu); | ||
591 | tick_nohz_update_jiffies(); | ||
592 | tick_nohz_kick_tick(cpu); | ||
593 | #endif | ||
594 | } | ||
595 | |||
596 | /* | ||
547 | * High resolution timer specific code | 597 | * High resolution timer specific code |
548 | */ | 598 | */ |
549 | #ifdef CONFIG_HIGH_RES_TIMERS | 599 | #ifdef CONFIG_HIGH_RES_TIMERS |
@@ -567,7 +617,7 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) | |||
567 | * this duty, then the jiffies update is still serialized by | 617 | * this duty, then the jiffies update is still serialized by |
568 | * xtime_lock. | 618 | * xtime_lock. |
569 | */ | 619 | */ |
570 | if (unlikely(tick_do_timer_cpu == -1)) | 620 | if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) |
571 | tick_do_timer_cpu = cpu; | 621 | tick_do_timer_cpu = cpu; |
572 | #endif | 622 | #endif |
573 | 623 | ||
@@ -596,10 +646,6 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) | |||
596 | profile_tick(CPU_PROFILING); | 646 | profile_tick(CPU_PROFILING); |
597 | } | 647 | } |
598 | 648 | ||
599 | /* Do not restart, when we are in the idle loop */ | ||
600 | if (ts->tick_stopped) | ||
601 | return HRTIMER_NORESTART; | ||
602 | |||
603 | hrtimer_forward(timer, now, tick_period); | 649 | hrtimer_forward(timer, now, tick_period); |
604 | 650 | ||
605 | return HRTIMER_RESTART; | 651 | return HRTIMER_RESTART; |
@@ -619,7 +665,7 @@ void tick_setup_sched_timer(void) | |||
619 | */ | 665 | */ |
620 | hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | 666 | hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); |
621 | ts->sched_timer.function = tick_sched_timer; | 667 | ts->sched_timer.function = tick_sched_timer; |
622 | ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ; | 668 | ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU; |
623 | 669 | ||
624 | /* Get the next period (per cpu) */ | 670 | /* Get the next period (per cpu) */ |
625 | ts->sched_timer.expires = tick_init_jiffy_update(); | 671 | ts->sched_timer.expires = tick_init_jiffy_update(); |
@@ -643,17 +689,21 @@ void tick_setup_sched_timer(void) | |||
643 | ts->nohz_mode = NOHZ_MODE_HIGHRES; | 689 | ts->nohz_mode = NOHZ_MODE_HIGHRES; |
644 | #endif | 690 | #endif |
645 | } | 691 | } |
692 | #endif /* HIGH_RES_TIMERS */ | ||
646 | 693 | ||
694 | #if defined CONFIG_NO_HZ || defined CONFIG_HIGH_RES_TIMERS | ||
647 | void tick_cancel_sched_timer(int cpu) | 695 | void tick_cancel_sched_timer(int cpu) |
648 | { | 696 | { |
649 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | 697 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); |
650 | 698 | ||
699 | # ifdef CONFIG_HIGH_RES_TIMERS | ||
651 | if (ts->sched_timer.base) | 700 | if (ts->sched_timer.base) |
652 | hrtimer_cancel(&ts->sched_timer); | 701 | hrtimer_cancel(&ts->sched_timer); |
702 | # endif | ||
653 | 703 | ||
654 | ts->nohz_mode = NOHZ_MODE_INACTIVE; | 704 | ts->nohz_mode = NOHZ_MODE_INACTIVE; |
655 | } | 705 | } |
656 | #endif /* HIGH_RES_TIMERS */ | 706 | #endif |
657 | 707 | ||
658 | /** | 708 | /** |
659 | * Async notification about clocksource changes | 709 | * Async notification about clocksource changes |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 5099c95b8aa2..e7acfb482a68 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -487,7 +487,7 @@ void update_wall_time(void) | |||
487 | #else | 487 | #else |
488 | offset = clock->cycle_interval; | 488 | offset = clock->cycle_interval; |
489 | #endif | 489 | #endif |
490 | clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift; | 490 | clock->xtime_nsec = (s64)xtime.tv_nsec << clock->shift; |
491 | 491 | ||
492 | /* normally this loop will run just once, however in the | 492 | /* normally this loop will run just once, however in the |
493 | * case of lost or late ticks, it will accumulate correctly. | 493 | * case of lost or late ticks, it will accumulate correctly. |
@@ -518,9 +518,12 @@ void update_wall_time(void) | |||
518 | /* correct the clock when NTP error is too big */ | 518 | /* correct the clock when NTP error is too big */ |
519 | clocksource_adjust(offset); | 519 | clocksource_adjust(offset); |
520 | 520 | ||
521 | /* store full nanoseconds into xtime */ | 521 | /* store full nanoseconds into xtime after rounding it up and |
522 | xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift; | 522 | * add the remainder to the error difference. |
523 | */ | ||
524 | xtime.tv_nsec = ((s64)clock->xtime_nsec >> clock->shift) + 1; | ||
523 | clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift; | 525 | clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift; |
526 | clock->error += clock->xtime_nsec << (NTP_SCALE_SHIFT - clock->shift); | ||
524 | 527 | ||
525 | update_xtime_cache(cyc2ns(clock, offset)); | 528 | update_xtime_cache(cyc2ns(clock, offset)); |
526 | 529 | ||
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index a40e20fd0001..f6426911e35a 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c | |||
@@ -47,13 +47,14 @@ static void print_name_offset(struct seq_file *m, void *sym) | |||
47 | } | 47 | } |
48 | 48 | ||
49 | static void | 49 | static void |
50 | print_timer(struct seq_file *m, struct hrtimer *timer, int idx, u64 now) | 50 | print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer, |
51 | int idx, u64 now) | ||
51 | { | 52 | { |
52 | #ifdef CONFIG_TIMER_STATS | 53 | #ifdef CONFIG_TIMER_STATS |
53 | char tmp[TASK_COMM_LEN + 1]; | 54 | char tmp[TASK_COMM_LEN + 1]; |
54 | #endif | 55 | #endif |
55 | SEQ_printf(m, " #%d: ", idx); | 56 | SEQ_printf(m, " #%d: ", idx); |
56 | print_name_offset(m, timer); | 57 | print_name_offset(m, taddr); |
57 | SEQ_printf(m, ", "); | 58 | SEQ_printf(m, ", "); |
58 | print_name_offset(m, timer->function); | 59 | print_name_offset(m, timer->function); |
59 | SEQ_printf(m, ", S:%02lx", timer->state); | 60 | SEQ_printf(m, ", S:%02lx", timer->state); |
@@ -99,7 +100,7 @@ next_one: | |||
99 | tmp = *timer; | 100 | tmp = *timer; |
100 | spin_unlock_irqrestore(&base->cpu_base->lock, flags); | 101 | spin_unlock_irqrestore(&base->cpu_base->lock, flags); |
101 | 102 | ||
102 | print_timer(m, &tmp, i, now); | 103 | print_timer(m, timer, &tmp, i, now); |
103 | next++; | 104 | next++; |
104 | goto next_one; | 105 | goto next_one; |
105 | } | 106 | } |
@@ -109,6 +110,7 @@ next_one: | |||
109 | static void | 110 | static void |
110 | print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now) | 111 | print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now) |
111 | { | 112 | { |
113 | SEQ_printf(m, " .base: %p\n", base); | ||
112 | SEQ_printf(m, " .index: %d\n", | 114 | SEQ_printf(m, " .index: %d\n", |
113 | base->index); | 115 | base->index); |
114 | SEQ_printf(m, " .resolution: %Lu nsecs\n", | 116 | SEQ_printf(m, " .resolution: %Lu nsecs\n", |
@@ -183,12 +185,16 @@ static void print_cpu(struct seq_file *m, int cpu, u64 now) | |||
183 | 185 | ||
184 | #ifdef CONFIG_GENERIC_CLOCKEVENTS | 186 | #ifdef CONFIG_GENERIC_CLOCKEVENTS |
185 | static void | 187 | static void |
186 | print_tickdevice(struct seq_file *m, struct tick_device *td) | 188 | print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu) |
187 | { | 189 | { |
188 | struct clock_event_device *dev = td->evtdev; | 190 | struct clock_event_device *dev = td->evtdev; |
189 | 191 | ||
190 | SEQ_printf(m, "\n"); | 192 | SEQ_printf(m, "\n"); |
191 | SEQ_printf(m, "Tick Device: mode: %d\n", td->mode); | 193 | SEQ_printf(m, "Tick Device: mode: %d\n", td->mode); |
194 | if (cpu < 0) | ||
195 | SEQ_printf(m, "Broadcast device\n"); | ||
196 | else | ||
197 | SEQ_printf(m, "Per CPU device: %d\n", cpu); | ||
192 | 198 | ||
193 | SEQ_printf(m, "Clock Event Device: "); | 199 | SEQ_printf(m, "Clock Event Device: "); |
194 | if (!dev) { | 200 | if (!dev) { |
@@ -222,7 +228,7 @@ static void timer_list_show_tickdevices(struct seq_file *m) | |||
222 | int cpu; | 228 | int cpu; |
223 | 229 | ||
224 | #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST | 230 | #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST |
225 | print_tickdevice(m, tick_get_broadcast_device()); | 231 | print_tickdevice(m, tick_get_broadcast_device(), -1); |
226 | SEQ_printf(m, "tick_broadcast_mask: %08lx\n", | 232 | SEQ_printf(m, "tick_broadcast_mask: %08lx\n", |
227 | tick_get_broadcast_mask()->bits[0]); | 233 | tick_get_broadcast_mask()->bits[0]); |
228 | #ifdef CONFIG_TICK_ONESHOT | 234 | #ifdef CONFIG_TICK_ONESHOT |
@@ -232,7 +238,7 @@ static void timer_list_show_tickdevices(struct seq_file *m) | |||
232 | SEQ_printf(m, "\n"); | 238 | SEQ_printf(m, "\n"); |
233 | #endif | 239 | #endif |
234 | for_each_online_cpu(cpu) | 240 | for_each_online_cpu(cpu) |
235 | print_tickdevice(m, tick_get_device(cpu)); | 241 | print_tickdevice(m, tick_get_device(cpu), cpu); |
236 | SEQ_printf(m, "\n"); | 242 | SEQ_printf(m, "\n"); |
237 | } | 243 | } |
238 | #else | 244 | #else |
@@ -244,7 +250,7 @@ static int timer_list_show(struct seq_file *m, void *v) | |||
244 | u64 now = ktime_to_ns(ktime_get()); | 250 | u64 now = ktime_to_ns(ktime_get()); |
245 | int cpu; | 251 | int cpu; |
246 | 252 | ||
247 | SEQ_printf(m, "Timer List Version: v0.3\n"); | 253 | SEQ_printf(m, "Timer List Version: v0.4\n"); |
248 | SEQ_printf(m, "HRTIMER_MAX_CLOCK_BASES: %d\n", HRTIMER_MAX_CLOCK_BASES); | 254 | SEQ_printf(m, "HRTIMER_MAX_CLOCK_BASES: %d\n", HRTIMER_MAX_CLOCK_BASES); |
249 | SEQ_printf(m, "now at %Ld nsecs\n", (unsigned long long)now); | 255 | SEQ_printf(m, "now at %Ld nsecs\n", (unsigned long long)now); |
250 | 256 | ||