diff options
Diffstat (limited to 'kernel/timer.c')
| -rw-r--r-- | kernel/timer.c | 137 |
1 files changed, 98 insertions, 39 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index aeb6a54f2771..9199f3c52215 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -319,6 +319,24 @@ unsigned long round_jiffies_up_relative(unsigned long j) | |||
| 319 | } | 319 | } |
| 320 | EXPORT_SYMBOL_GPL(round_jiffies_up_relative); | 320 | EXPORT_SYMBOL_GPL(round_jiffies_up_relative); |
| 321 | 321 | ||
| 322 | /** | ||
| 323 | * set_timer_slack - set the allowed slack for a timer | ||
| 324 | * @slack_hz: the amount of time (in jiffies) allowed for rounding | ||
| 325 | * | ||
| 326 | * Set the amount of time, in jiffies, that a certain timer has | ||
| 327 | * in terms of slack. By setting this value, the timer subsystem | ||
| 328 | * will schedule the actual timer somewhere between | ||
| 329 | * the time mod_timer() asks for, and that time plus the slack. | ||
| 330 | * | ||
| 331 | * By setting the slack to -1, a percentage of the delay is used | ||
| 332 | * instead. | ||
| 333 | */ | ||
| 334 | void set_timer_slack(struct timer_list *timer, int slack_hz) | ||
| 335 | { | ||
| 336 | timer->slack = slack_hz; | ||
| 337 | } | ||
| 338 | EXPORT_SYMBOL_GPL(set_timer_slack); | ||
| 339 | |||
| 322 | 340 | ||
| 323 | static inline void set_running_timer(struct tvec_base *base, | 341 | static inline void set_running_timer(struct tvec_base *base, |
| 324 | struct timer_list *timer) | 342 | struct timer_list *timer) |
| @@ -550,6 +568,7 @@ static void __init_timer(struct timer_list *timer, | |||
| 550 | { | 568 | { |
| 551 | timer->entry.next = NULL; | 569 | timer->entry.next = NULL; |
| 552 | timer->base = __raw_get_cpu_var(tvec_bases); | 570 | timer->base = __raw_get_cpu_var(tvec_bases); |
| 571 | timer->slack = -1; | ||
| 553 | #ifdef CONFIG_TIMER_STATS | 572 | #ifdef CONFIG_TIMER_STATS |
| 554 | timer->start_site = NULL; | 573 | timer->start_site = NULL; |
| 555 | timer->start_pid = -1; | 574 | timer->start_pid = -1; |
| @@ -715,6 +734,41 @@ int mod_timer_pending(struct timer_list *timer, unsigned long expires) | |||
| 715 | } | 734 | } |
| 716 | EXPORT_SYMBOL(mod_timer_pending); | 735 | EXPORT_SYMBOL(mod_timer_pending); |
| 717 | 736 | ||
| 737 | /* | ||
| 738 | * Decide where to put the timer while taking the slack into account | ||
| 739 | * | ||
| 740 | * Algorithm: | ||
| 741 | * 1) calculate the maximum (absolute) time | ||
| 742 | * 2) calculate the highest bit where the expires and new max are different | ||
| 743 | * 3) use this bit to make a mask | ||
| 744 | * 4) use the bitmask to round down the maximum time, so that all last | ||
| 745 | * bits are zeros | ||
| 746 | */ | ||
| 747 | static inline | ||
| 748 | unsigned long apply_slack(struct timer_list *timer, unsigned long expires) | ||
| 749 | { | ||
| 750 | unsigned long expires_limit, mask; | ||
| 751 | int bit; | ||
| 752 | |||
| 753 | expires_limit = expires + timer->slack; | ||
| 754 | |||
| 755 | if (timer->slack < 0) /* auto slack: use 0.4% */ | ||
| 756 | expires_limit = expires + (expires - jiffies)/256; | ||
| 757 | |||
| 758 | mask = expires ^ expires_limit; | ||
| 759 | |||
| 760 | if (mask == 0) | ||
| 761 | return expires; | ||
| 762 | |||
| 763 | bit = find_last_bit(&mask, BITS_PER_LONG); | ||
| 764 | |||
| 765 | mask = (1 << bit) - 1; | ||
| 766 | |||
| 767 | expires_limit = expires_limit & ~(mask); | ||
| 768 | |||
| 769 | return expires_limit; | ||
| 770 | } | ||
| 771 | |||
| 718 | /** | 772 | /** |
| 719 | * mod_timer - modify a timer's timeout | 773 | * mod_timer - modify a timer's timeout |
| 720 | * @timer: the timer to be modified | 774 | * @timer: the timer to be modified |
| @@ -745,6 +799,8 @@ int mod_timer(struct timer_list *timer, unsigned long expires) | |||
| 745 | if (timer_pending(timer) && timer->expires == expires) | 799 | if (timer_pending(timer) && timer->expires == expires) |
| 746 | return 1; | 800 | return 1; |
| 747 | 801 | ||
| 802 | expires = apply_slack(timer, expires); | ||
| 803 | |||
| 748 | return __mod_timer(timer, expires, false, TIMER_NOT_PINNED); | 804 | return __mod_timer(timer, expires, false, TIMER_NOT_PINNED); |
| 749 | } | 805 | } |
| 750 | EXPORT_SYMBOL(mod_timer); | 806 | EXPORT_SYMBOL(mod_timer); |
| @@ -955,6 +1011,47 @@ static int cascade(struct tvec_base *base, struct tvec *tv, int index) | |||
| 955 | return index; | 1011 | return index; |
| 956 | } | 1012 | } |
| 957 | 1013 | ||
| 1014 | static void call_timer_fn(struct timer_list *timer, void (*fn)(unsigned long), | ||
| 1015 | unsigned long data) | ||
| 1016 | { | ||
| 1017 | int preempt_count = preempt_count(); | ||
| 1018 | |||
| 1019 | #ifdef CONFIG_LOCKDEP | ||
| 1020 | /* | ||
| 1021 | * It is permissible to free the timer from inside the | ||
| 1022 | * function that is called from it, this we need to take into | ||
| 1023 | * account for lockdep too. To avoid bogus "held lock freed" | ||
| 1024 | * warnings as well as problems when looking into | ||
| 1025 | * timer->lockdep_map, make a copy and use that here. | ||
| 1026 | */ | ||
| 1027 | struct lockdep_map lockdep_map = timer->lockdep_map; | ||
| 1028 | #endif | ||
| 1029 | /* | ||
| 1030 | * Couple the lock chain with the lock chain at | ||
| 1031 | * del_timer_sync() by acquiring the lock_map around the fn() | ||
| 1032 | * call here and in del_timer_sync(). | ||
| 1033 | */ | ||
| 1034 | lock_map_acquire(&lockdep_map); | ||
| 1035 | |||
| 1036 | trace_timer_expire_entry(timer); | ||
| 1037 | fn(data); | ||
| 1038 | trace_timer_expire_exit(timer); | ||
| 1039 | |||
| 1040 | lock_map_release(&lockdep_map); | ||
| 1041 | |||
| 1042 | if (preempt_count != preempt_count()) { | ||
| 1043 | WARN_ONCE(1, "timer: %pF preempt leak: %08x -> %08x\n", | ||
| 1044 | fn, preempt_count, preempt_count()); | ||
| 1045 | /* | ||
| 1046 | * Restore the preempt count. That gives us a decent | ||
| 1047 | * chance to survive and extract information. If the | ||
| 1048 | * callback kept a lock held, bad luck, but not worse | ||
| 1049 | * than the BUG() we had. | ||
| 1050 | */ | ||
| 1051 | preempt_count() = preempt_count; | ||
| 1052 | } | ||
| 1053 | } | ||
| 1054 | |||
| 958 | #define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK) | 1055 | #define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK) |
| 959 | 1056 | ||
| 960 | /** | 1057 | /** |
| @@ -998,45 +1095,7 @@ static inline void __run_timers(struct tvec_base *base) | |||
| 998 | detach_timer(timer, 1); | 1095 | detach_timer(timer, 1); |
| 999 | 1096 | ||
| 1000 | spin_unlock_irq(&base->lock); | 1097 | spin_unlock_irq(&base->lock); |
| 1001 | { | 1098 | call_timer_fn(timer, fn, data); |
| 1002 | int preempt_count = preempt_count(); | ||
| 1003 | |||
| 1004 | #ifdef CONFIG_LOCKDEP | ||
| 1005 | /* | ||
| 1006 | * It is permissible to free the timer from | ||
| 1007 | * inside the function that is called from | ||
| 1008 | * it, this we need to take into account for | ||
| 1009 | * lockdep too. To avoid bogus "held lock | ||
| 1010 | * freed" warnings as well as problems when | ||
| 1011 | * looking into timer->lockdep_map, make a | ||
| 1012 | * copy and use that here. | ||
| 1013 | */ | ||
| 1014 | struct lockdep_map lockdep_map = | ||
| 1015 | timer->lockdep_map; | ||
| 1016 | #endif | ||
| 1017 | /* | ||
| 1018 | * Couple the lock chain with the lock chain at | ||
| 1019 | * del_timer_sync() by acquiring the lock_map | ||
| 1020 | * around the fn() call here and in | ||
| 1021 | * del_timer_sync(). | ||
| 1022 | */ | ||
| 1023 | lock_map_acquire(&lockdep_map); | ||
| 1024 | |||
| 1025 | trace_timer_expire_entry(timer); | ||
| 1026 | fn(data); | ||
| 1027 | trace_timer_expire_exit(timer); | ||
| 1028 | |||
| 1029 | lock_map_release(&lockdep_map); | ||
| 1030 | |||
| 1031 | if (preempt_count != preempt_count()) { | ||
| 1032 | printk(KERN_ERR "huh, entered %p " | ||
| 1033 | "with preempt_count %08x, exited" | ||
| 1034 | " with %08x?\n", | ||
| 1035 | fn, preempt_count, | ||
| 1036 | preempt_count()); | ||
| 1037 | BUG(); | ||
| 1038 | } | ||
| 1039 | } | ||
| 1040 | spin_lock_irq(&base->lock); | 1099 | spin_lock_irq(&base->lock); |
| 1041 | } | 1100 | } |
| 1042 | } | 1101 | } |
