diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2007-05-01 00:24:54 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-05-01 00:24:54 -0400 |
commit | bc95f3669f5e6f63cf0b84fe4922c3c6dd4aa775 (patch) | |
tree | 427fcf2a7287c16d4b5aa6cbf494d59579a6a8b1 /kernel/timer.c | |
parent | 3d29cdff999c37b3876082278a8134a0642a02cd (diff) | |
parent | dc87c3985e9b442c60994308a96f887579addc39 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/usb/input/Makefile
drivers/usb/input/gtco.c
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 42 |
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 | ||
508 | EXPORT_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 | */ |
715 | unsigned long get_next_timer_interrupt(unsigned long now) | 731 | unsigned 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 | */ |
913 | int timekeeping_is_continuous(void) | 931 | int 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 | } |