aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/timer.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2010-05-25 14:43:30 -0400
committerThomas Gleixner <tglx@linutronix.de>2010-05-25 15:07:48 -0400
commit8e63d7795e30b4091e303cc8c060509bd8eea742 (patch)
treed5433cf6b0a57b72b0220ff8e1d89ceca6fbd49c /kernel/timer.c
parentf16a5e347835c6a0ba958535cf6e6c89d50463b8 (diff)
timers: Fix slack calculation really
commit f00e047ef (timers: Fix slack calculation for expired timers) fixed the issue of slack on expired timers only partially. Linus noticed that jiffies is volatile so it is reloaded twice, which generates bad code. But its worse. This can defeat the time_after() check if jiffies are incremented between time_after() and the slack calculation. Fix it by reading jiffies into a local variable, which prevents the compiler from loading it twice. While at it make the > -1 check into >= 0 which is easier to read. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/timer.c')
-rw-r--r--kernel/timer.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/kernel/timer.c b/kernel/timer.c
index be394af5bc22..d8decb8d46b0 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -747,16 +747,19 @@ EXPORT_SYMBOL(mod_timer_pending);
747static inline 747static inline
748unsigned long apply_slack(struct timer_list *timer, unsigned long expires) 748unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
749{ 749{
750 unsigned long expires_limit, mask; 750 unsigned long expires_limit, mask, now;
751 int bit; 751 int bit;
752 752
753 expires_limit = expires; 753 expires_limit = expires;
754 754
755 if (timer->slack > -1) 755 if (timer->slack >= 0) {
756 expires_limit = expires + timer->slack; 756 expires_limit = expires + timer->slack;
757 else if (time_after(expires, jiffies)) /* auto slack: use 0.4% */ 757 } else {
758 expires_limit = expires + (expires - jiffies)/256; 758 now = jiffies;
759 759 /* No slack, if already expired else auto slack 0.4% */
760 if (time_after(expires, now))
761 expires_limit = expires + (expires - now)/256;
762 }
760 mask = expires ^ expires_limit; 763 mask = expires ^ expires_limit;
761 if (mask == 0) 764 if (mask == 0)
762 return expires; 765 return expires;