From 8e63d7795e30b4091e303cc8c060509bd8eea742 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 25 May 2010 20:43:30 +0200 Subject: 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 Cc: Arjan van de Ven Cc: Linus Torvalds --- kernel/timer.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'kernel/timer.c') 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); static inline unsigned long apply_slack(struct timer_list *timer, unsigned long expires) { - unsigned long expires_limit, mask; + unsigned long expires_limit, mask, now; int bit; expires_limit = expires; - if (timer->slack > -1) + if (timer->slack >= 0) { expires_limit = expires + timer->slack; - else if (time_after(expires, jiffies)) /* auto slack: use 0.4% */ - expires_limit = expires + (expires - jiffies)/256; - + } else { + now = jiffies; + /* No slack, if already expired else auto slack 0.4% */ + if (time_after(expires, now)) + expires_limit = expires + (expires - now)/256; + } mask = expires ^ expires_limit; if (mask == 0) return expires; -- cgit v1.2.3 From 2abfb9e1d470f7082e5e20e4b11a271a0124211b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 26 May 2010 16:07:13 +0200 Subject: timers: Move local variable into else section Fix nit-picking coding style detail. Signed-off-by: Thomas Gleixner --- kernel/timer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'kernel/timer.c') diff --git a/kernel/timer.c b/kernel/timer.c index d8decb8d46b0..22118342a456 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -747,7 +747,7 @@ EXPORT_SYMBOL(mod_timer_pending); static inline unsigned long apply_slack(struct timer_list *timer, unsigned long expires) { - unsigned long expires_limit, mask, now; + unsigned long expires_limit, mask; int bit; expires_limit = expires; @@ -755,7 +755,8 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires) if (timer->slack >= 0) { expires_limit = expires + timer->slack; } else { - now = jiffies; + unsigned long now = jiffies; + /* No slack, if already expired else auto slack 0.4% */ if (time_after(expires, now)) expires_limit = expires + (expires - now)/256; -- cgit v1.2.3