Commit fd064b9b7770d5c7705bf9542950c7bd81c30f98
Committed by
Linus Torvalds
1 parent
1cfd68496e
Exists in
master
and in
39 other branches
[PATCH] Extend next_timer_interrupt() to use a reference jiffie
For CONFIG_NO_HZ we need to calculate the next timer wheel event based on a given jiffie value. Extend the existing code to allow the extra 'now' argument. Provide a compability function for the existing implementations to call the function with now == jiffies. (This also solves the racyness of the original code vs. jiffies changing during the iteration.) No functional changes to existing users of this infrastructure. [ remove WARN_ON() that triggered on s390, by Carsten Otte <cotte@de.ibm.com> ] [ made new helper static, Adrian Bunk <bunk@stusta.de> ] Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: john stultz <johnstul@us.ibm.com> Cc: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 3 changed files with 22 additions and 4 deletions Side-by-side Diff
include/linux/timer.h
... | ... | @@ -61,7 +61,17 @@ |
61 | 61 | extern int __mod_timer(struct timer_list *timer, unsigned long expires); |
62 | 62 | extern int mod_timer(struct timer_list *timer, unsigned long expires); |
63 | 63 | |
64 | +/* | |
65 | + * Return when the next timer-wheel timeout occurs (in absolute jiffies), | |
66 | + * locks the timer base: | |
67 | + */ | |
64 | 68 | extern unsigned long next_timer_interrupt(void); |
69 | +/* | |
70 | + * Return when the next timer-wheel timeout occurs (in absolute jiffies), | |
71 | + * locks the timer base and does the comparison against the given | |
72 | + * jiffie. | |
73 | + */ | |
74 | +extern unsigned long get_next_timer_interrupt(unsigned long now); | |
65 | 75 | |
66 | 76 | /** |
67 | 77 | * add_timer - start a timer |
kernel/hrtimer.c
kernel/timer.c
... | ... | @@ -591,7 +591,7 @@ |
591 | 591 | spin_unlock_irq(&base->lock); |
592 | 592 | } |
593 | 593 | |
594 | -#ifdef CONFIG_NO_IDLE_HZ | |
594 | +#if defined(CONFIG_NO_IDLE_HZ) || defined(CONFIG_NO_HZ) | |
595 | 595 | /* |
596 | 596 | * Find out when the next timer event is due to happen. This |
597 | 597 | * is used on S/390 to stop all activity when a cpus is idle. |
598 | 598 | |
... | ... | @@ -687,10 +687,10 @@ |
687 | 687 | /** |
688 | 688 | * next_timer_interrupt - return the jiffy of the next pending timer |
689 | 689 | */ |
690 | -unsigned long next_timer_interrupt(void) | |
690 | +unsigned long get_next_timer_interrupt(unsigned long now) | |
691 | 691 | { |
692 | 692 | tvec_base_t *base = __get_cpu_var(tvec_bases); |
693 | - unsigned long expires, now = jiffies; | |
693 | + unsigned long expires; | |
694 | 694 | |
695 | 695 | spin_lock(&base->lock); |
696 | 696 | expires = __next_timer_interrupt(base); |
... | ... | @@ -701,6 +701,14 @@ |
701 | 701 | |
702 | 702 | return cmp_next_hrtimer_event(now, expires); |
703 | 703 | } |
704 | + | |
705 | +#ifdef CONFIG_NO_IDLE_HZ | |
706 | +unsigned long next_timer_interrupt(void) | |
707 | +{ | |
708 | + return get_next_timer_interrupt(jiffies); | |
709 | +} | |
710 | +#endif | |
711 | + | |
704 | 712 | #endif |
705 | 713 | |
706 | 714 | /******************************************************************/ |