diff options
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 0b36b9e5cc8b..5c1e49ec2f1b 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: |
@@ -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)) |
@@ -1523,6 +1541,7 @@ static int __cpuinit init_timers_cpu(int cpu) | |||
1523 | INIT_LIST_HEAD(base->tv1.vec + j); | 1541 | INIT_LIST_HEAD(base->tv1.vec + j); |
1524 | 1542 | ||
1525 | base->timer_jiffies = jiffies; | 1543 | base->timer_jiffies = jiffies; |
1544 | base->next_timer = base->timer_jiffies; | ||
1526 | return 0; | 1545 | return 0; |
1527 | } | 1546 | } |
1528 | 1547 | ||
@@ -1535,6 +1554,9 @@ static void migrate_timer_list(struct tvec_base *new_base, struct list_head *hea | |||
1535 | timer = list_first_entry(head, struct timer_list, entry); | 1554 | timer = list_first_entry(head, struct timer_list, entry); |
1536 | detach_timer(timer, 0); | 1555 | detach_timer(timer, 0); |
1537 | timer_set_base(timer, new_base); | 1556 | timer_set_base(timer, new_base); |
1557 | if (time_before(timer->expires, new_base->next_timer) && | ||
1558 | !tbase_get_deferrable(timer->base)) | ||
1559 | new_base->next_timer = timer->expires; | ||
1538 | internal_add_timer(new_base, timer); | 1560 | internal_add_timer(new_base, timer); |
1539 | } | 1561 | } |
1540 | } | 1562 | } |