aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2007-02-16 04:27:47 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-16 11:13:58 -0500
commitfd064b9b7770d5c7705bf9542950c7bd81c30f98 (patch)
tree8b14c81f983e49b5553fd6764139bffb1d4f1648
parent1cfd68496e53f7be09a3c1358d1d389004217541 (diff)
[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>
-rw-r--r--include/linux/timer.h10
-rw-r--r--kernel/hrtimer.c2
-rw-r--r--kernel/timer.c14
3 files changed, 22 insertions, 4 deletions
diff --git a/include/linux/timer.h b/include/linux/timer.h
index fb5edaaf0ebd..bd0af324fd48 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -61,7 +61,17 @@ extern int del_timer(struct timer_list * timer);
61extern int __mod_timer(struct timer_list *timer, unsigned long expires); 61extern int __mod_timer(struct timer_list *timer, unsigned long expires);
62extern int mod_timer(struct timer_list *timer, unsigned long expires); 62extern 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 */
64extern unsigned long next_timer_interrupt(void); 68extern 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 */
74extern unsigned long get_next_timer_interrupt(unsigned long now);
65 75
66/** 76/**
67 * add_timer - start a timer 77 * add_timer - start a timer
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index c0fdb9b6d296..bd57ef403049 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -533,7 +533,7 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
533} 533}
534EXPORT_SYMBOL_GPL(hrtimer_get_remaining); 534EXPORT_SYMBOL_GPL(hrtimer_get_remaining);
535 535
536#ifdef CONFIG_NO_IDLE_HZ 536#if defined(CONFIG_NO_IDLE_HZ) || defined(CONFIG_NO_HZ)
537/** 537/**
538 * hrtimer_get_next_event - get the time until next expiry event 538 * hrtimer_get_next_event - get the time until next expiry event
539 * 539 *
diff --git a/kernel/timer.c b/kernel/timer.c
index 201bee07b8e0..6d843e100e75 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -591,7 +591,7 @@ static inline void __run_timers(tvec_base_t *base)
591 spin_unlock_irq(&base->lock); 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 * Find out when the next timer event is due to happen. This 596 * Find out when the next timer event is due to happen. This
597 * is used on S/390 to stop all activity when a cpus is idle. 597 * is used on S/390 to stop all activity when a cpus is idle.
@@ -687,10 +687,10 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now,
687/** 687/**
688 * next_timer_interrupt - return the jiffy of the next pending timer 688 * next_timer_interrupt - return the jiffy of the next pending timer
689 */ 689 */
690unsigned long next_timer_interrupt(void) 690unsigned long get_next_timer_interrupt(unsigned long now)
691{ 691{
692 tvec_base_t *base = __get_cpu_var(tvec_bases); 692 tvec_base_t *base = __get_cpu_var(tvec_bases);
693 unsigned long expires, now = jiffies; 693 unsigned long expires;
694 694
695 spin_lock(&base->lock); 695 spin_lock(&base->lock);
696 expires = __next_timer_interrupt(base); 696 expires = __next_timer_interrupt(base);
@@ -701,6 +701,14 @@ unsigned long next_timer_interrupt(void)
701 701
702 return cmp_next_hrtimer_event(now, expires); 702 return cmp_next_hrtimer_event(now, expires);
703} 703}
704
705#ifdef CONFIG_NO_IDLE_HZ
706unsigned long next_timer_interrupt(void)
707{
708 return get_next_timer_interrupt(jiffies);
709}
710#endif
711
704#endif 712#endif
705 713
706/******************************************************************/ 714/******************************************************************/