Commit fd064b9b7770d5c7705bf9542950c7bd81c30f98

Authored by Thomas Gleixner
Committed by Linus Torvalds
1 parent 1cfd68496e

[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
... ... @@ -533,7 +533,7 @@
533 533 }
534 534 EXPORT_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 538 * hrtimer_get_next_event - get the time until next expiry event
539 539 *
... ... @@ -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 /******************************************************************/