aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/timer.c')
-rw-r--r--kernel/timer.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/kernel/timer.c b/kernel/timer.c
index cb1b86a9c52f..b22bd39740dd 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -505,6 +505,8 @@ out:
505 return ret; 505 return ret;
506} 506}
507 507
508EXPORT_SYMBOL(try_to_del_timer_sync);
509
508/** 510/**
509 * del_timer_sync - deactivate a timer and wait for the handler to finish. 511 * del_timer_sync - deactivate a timer and wait for the handler to finish.
510 * @timer: the timer to be deactivated 512 * @timer: the timer to be deactivated
@@ -695,15 +697,28 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now,
695{ 697{
696 ktime_t hr_delta = hrtimer_get_next_event(); 698 ktime_t hr_delta = hrtimer_get_next_event();
697 struct timespec tsdelta; 699 struct timespec tsdelta;
700 unsigned long delta;
698 701
699 if (hr_delta.tv64 == KTIME_MAX) 702 if (hr_delta.tv64 == KTIME_MAX)
700 return expires; 703 return expires;
701 704
702 if (hr_delta.tv64 <= TICK_NSEC) 705 /*
703 return now; 706 * Expired timer available, let it expire in the next tick
707 */
708 if (hr_delta.tv64 <= 0)
709 return now + 1;
704 710
705 tsdelta = ktime_to_timespec(hr_delta); 711 tsdelta = ktime_to_timespec(hr_delta);
706 now += timespec_to_jiffies(&tsdelta); 712 delta = timespec_to_jiffies(&tsdelta);
713 /*
714 * Take rounding errors in to account and make sure, that it
715 * expires in the next tick. Otherwise we go into an endless
716 * ping pong due to tick_nohz_stop_sched_tick() retriggering
717 * the timer softirq
718 */
719 if (delta < 1)
720 delta = 1;
721 now += delta;
707 if (time_before(now, expires)) 722 if (time_before(now, expires))
708 return now; 723 return now;
709 return expires; 724 return expires;
@@ -711,6 +726,7 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now,
711 726
712/** 727/**
713 * next_timer_interrupt - return the jiffy of the next pending timer 728 * next_timer_interrupt - return the jiffy of the next pending timer
729 * @now: current time (in jiffies)
714 */ 730 */
715unsigned long get_next_timer_interrupt(unsigned long now) 731unsigned long get_next_timer_interrupt(unsigned long now)
716{ 732{
@@ -861,6 +877,8 @@ int do_settimeofday(struct timespec *tv)
861 clock->error = 0; 877 clock->error = 0;
862 ntp_clear(); 878 ntp_clear();
863 879
880 update_vsyscall(&xtime, clock);
881
864 write_sequnlock_irqrestore(&xtime_lock, flags); 882 write_sequnlock_irqrestore(&xtime_lock, flags);
865 883
866 /* signal hrtimers about time change */ 884 /* signal hrtimers about time change */
@@ -908,7 +926,7 @@ static inline void change_clocksource(void) { }
908#endif 926#endif
909 927
910/** 928/**
911 * timeofday_is_continuous - check to see if timekeeping is free running 929 * timekeeping_is_continuous - check to see if timekeeping is free running
912 */ 930 */
913int timekeeping_is_continuous(void) 931int timekeeping_is_continuous(void)
914{ 932{
@@ -996,8 +1014,11 @@ static int timekeeping_resume(struct sys_device *dev)
996 write_sequnlock_irqrestore(&xtime_lock, flags); 1014 write_sequnlock_irqrestore(&xtime_lock, flags);
997 1015
998 touch_softlockup_watchdog(); 1016 touch_softlockup_watchdog();
1017
1018 clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
1019
999 /* Resume hrtimers */ 1020 /* Resume hrtimers */
1000 clock_was_set(); 1021 hres_timers_resume();
1001 1022
1002 return 0; 1023 return 0;
1003} 1024}
@@ -1010,6 +1031,9 @@ static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
1010 timekeeping_suspended = 1; 1031 timekeeping_suspended = 1;
1011 timekeeping_suspend_time = read_persistent_clock(); 1032 timekeeping_suspend_time = read_persistent_clock();
1012 write_sequnlock_irqrestore(&xtime_lock, flags); 1033 write_sequnlock_irqrestore(&xtime_lock, flags);
1034
1035 clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
1036
1013 return 0; 1037 return 0;
1014} 1038}
1015 1039
@@ -1650,8 +1674,8 @@ static void __devinit migrate_timers(int cpu)
1650 new_base = get_cpu_var(tvec_bases); 1674 new_base = get_cpu_var(tvec_bases);
1651 1675
1652 local_irq_disable(); 1676 local_irq_disable();
1653 spin_lock(&new_base->lock); 1677 double_spin_lock(&new_base->lock, &old_base->lock,
1654 spin_lock(&old_base->lock); 1678 smp_processor_id() < cpu);
1655 1679
1656 BUG_ON(old_base->running_timer); 1680 BUG_ON(old_base->running_timer);
1657 1681
@@ -1664,8 +1688,8 @@ static void __devinit migrate_timers(int cpu)
1664 migrate_timer_list(new_base, old_base->tv5.vec + i); 1688 migrate_timer_list(new_base, old_base->tv5.vec + i);
1665 } 1689 }
1666 1690
1667 spin_unlock(&old_base->lock); 1691 double_spin_unlock(&new_base->lock, &old_base->lock,
1668 spin_unlock(&new_base->lock); 1692 smp_processor_id() < cpu);
1669 local_irq_enable(); 1693 local_irq_enable();
1670 put_cpu_var(tvec_bases); 1694 put_cpu_var(tvec_bases);
1671} 1695}