diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-09-21 06:51:27 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-09-21 06:51:42 -0400 |
| commit | ae82bfd61ca7e57cc2d914add9ab0873e260f2f5 (patch) | |
| tree | a7f862ad8b0ae4f2e8953e6aa613eb702b484ecf /kernel/timer.c | |
| parent | cd74c86bdf705f824d494a2bbda393d1d562b40a (diff) | |
| parent | ebc79c4f8da0f92efa968e0328f32334a2ce80cf (diff) | |
Merge branch 'linus' into perfcounters/rename
Merge reason: pull in all the latest code before doing the rename.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/timer.c')
| -rw-r--r-- | kernel/timer.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index a3d25f415019..bbb51074680e 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -72,6 +72,7 @@ struct tvec_base { | |||
| 72 | spinlock_t lock; | 72 | spinlock_t lock; |
| 73 | struct timer_list *running_timer; | 73 | struct timer_list *running_timer; |
| 74 | unsigned long timer_jiffies; | 74 | unsigned long timer_jiffies; |
| 75 | unsigned long next_timer; | ||
| 75 | struct tvec_root tv1; | 76 | struct tvec_root tv1; |
| 76 | struct tvec tv2; | 77 | struct tvec tv2; |
| 77 | struct tvec tv3; | 78 | struct tvec tv3; |
| @@ -622,6 +623,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires, | |||
| 622 | 623 | ||
| 623 | if (timer_pending(timer)) { | 624 | if (timer_pending(timer)) { |
| 624 | detach_timer(timer, 0); | 625 | detach_timer(timer, 0); |
| 626 | if (timer->expires == base->next_timer && | ||
| 627 | !tbase_get_deferrable(timer->base)) | ||
| 628 | base->next_timer = base->timer_jiffies; | ||
| 625 | ret = 1; | 629 | ret = 1; |
| 626 | } else { | 630 | } else { |
| 627 | if (pending_only) | 631 | if (pending_only) |
| @@ -663,6 +667,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires, | |||
| 663 | } | 667 | } |
| 664 | 668 | ||
| 665 | timer->expires = expires; | 669 | timer->expires = expires; |
| 670 | if (time_before(timer->expires, base->next_timer) && | ||
| 671 | !tbase_get_deferrable(timer->base)) | ||
| 672 | base->next_timer = timer->expires; | ||
| 666 | internal_add_timer(base, timer); | 673 | internal_add_timer(base, timer); |
| 667 | 674 | ||
| 668 | out_unlock: | 675 | out_unlock: |
| @@ -781,6 +788,9 @@ void add_timer_on(struct timer_list *timer, int cpu) | |||
| 781 | spin_lock_irqsave(&base->lock, flags); | 788 | spin_lock_irqsave(&base->lock, flags); |
| 782 | timer_set_base(timer, base); | 789 | timer_set_base(timer, base); |
| 783 | debug_timer_activate(timer); | 790 | debug_timer_activate(timer); |
| 791 | if (time_before(timer->expires, base->next_timer) && | ||
| 792 | !tbase_get_deferrable(timer->base)) | ||
| 793 | base->next_timer = timer->expires; | ||
| 784 | internal_add_timer(base, timer); | 794 | internal_add_timer(base, timer); |
| 785 | /* | 795 | /* |
| 786 | * Check whether the other CPU is idle and needs to be | 796 | * Check whether the other CPU is idle and needs to be |
| @@ -817,6 +827,9 @@ int del_timer(struct timer_list *timer) | |||
| 817 | base = lock_timer_base(timer, &flags); | 827 | base = lock_timer_base(timer, &flags); |
| 818 | if (timer_pending(timer)) { | 828 | if (timer_pending(timer)) { |
| 819 | detach_timer(timer, 1); | 829 | detach_timer(timer, 1); |
| 830 | if (timer->expires == base->next_timer && | ||
| 831 | !tbase_get_deferrable(timer->base)) | ||
| 832 | base->next_timer = base->timer_jiffies; | ||
| 820 | ret = 1; | 833 | ret = 1; |
| 821 | } | 834 | } |
| 822 | spin_unlock_irqrestore(&base->lock, flags); | 835 | spin_unlock_irqrestore(&base->lock, flags); |
| @@ -850,6 +863,9 @@ int try_to_del_timer_sync(struct timer_list *timer) | |||
| 850 | ret = 0; | 863 | ret = 0; |
| 851 | if (timer_pending(timer)) { | 864 | if (timer_pending(timer)) { |
| 852 | detach_timer(timer, 1); | 865 | detach_timer(timer, 1); |
| 866 | if (timer->expires == base->next_timer && | ||
| 867 | !tbase_get_deferrable(timer->base)) | ||
| 868 | base->next_timer = base->timer_jiffies; | ||
| 853 | ret = 1; | 869 | ret = 1; |
| 854 | } | 870 | } |
| 855 | out: | 871 | out: |
| @@ -1007,8 +1023,8 @@ static inline void __run_timers(struct tvec_base *base) | |||
| 1007 | #ifdef CONFIG_NO_HZ | 1023 | #ifdef CONFIG_NO_HZ |
| 1008 | /* | 1024 | /* |
| 1009 | * Find out when the next timer event is due to happen. This | 1025 | * Find out when the next timer event is due to happen. This |
| 1010 | * is used on S/390 to stop all activity when a cpus is idle. | 1026 | * is used on S/390 to stop all activity when a CPU is idle. |
| 1011 | * This functions needs to be called disabled. | 1027 | * This function needs to be called with interrupts disabled. |
| 1012 | */ | 1028 | */ |
| 1013 | static unsigned long __next_timer_interrupt(struct tvec_base *base) | 1029 | static unsigned long __next_timer_interrupt(struct tvec_base *base) |
| 1014 | { | 1030 | { |
| @@ -1134,7 +1150,9 @@ unsigned long get_next_timer_interrupt(unsigned long now) | |||
| 1134 | unsigned long expires; | 1150 | unsigned long expires; |
| 1135 | 1151 | ||
| 1136 | spin_lock(&base->lock); | 1152 | spin_lock(&base->lock); |
| 1137 | expires = __next_timer_interrupt(base); | 1153 | if (time_before_eq(base->next_timer, base->timer_jiffies)) |
| 1154 | base->next_timer = __next_timer_interrupt(base); | ||
| 1155 | expires = base->next_timer; | ||
| 1138 | spin_unlock(&base->lock); | 1156 | spin_unlock(&base->lock); |
| 1139 | 1157 | ||
| 1140 | if (time_before_eq(expires, now)) | 1158 | if (time_before_eq(expires, now)) |
| @@ -1522,6 +1540,7 @@ static int __cpuinit init_timers_cpu(int cpu) | |||
| 1522 | INIT_LIST_HEAD(base->tv1.vec + j); | 1540 | INIT_LIST_HEAD(base->tv1.vec + j); |
| 1523 | 1541 | ||
| 1524 | base->timer_jiffies = jiffies; | 1542 | base->timer_jiffies = jiffies; |
| 1543 | base->next_timer = base->timer_jiffies; | ||
| 1525 | return 0; | 1544 | return 0; |
| 1526 | } | 1545 | } |
| 1527 | 1546 | ||
| @@ -1534,6 +1553,9 @@ static void migrate_timer_list(struct tvec_base *new_base, struct list_head *hea | |||
| 1534 | timer = list_first_entry(head, struct timer_list, entry); | 1553 | timer = list_first_entry(head, struct timer_list, entry); |
| 1535 | detach_timer(timer, 0); | 1554 | detach_timer(timer, 0); |
| 1536 | timer_set_base(timer, new_base); | 1555 | timer_set_base(timer, new_base); |
| 1556 | if (time_before(timer->expires, new_base->next_timer) && | ||
| 1557 | !tbase_get_deferrable(timer->base)) | ||
| 1558 | new_base->next_timer = timer->expires; | ||
| 1537 | internal_add_timer(new_base, timer); | 1559 | internal_add_timer(new_base, timer); |
| 1538 | } | 1560 | } |
| 1539 | } | 1561 | } |
