The rework of next_timer_interrupt() fixed the timer wheel bugs, but
invented a rounding error versus the next hrtimer event. This is caused
by the conversion of the hrtimer internal representation to relative
jiffies.

This causes bug #8100:
http://bugzilla.kernel.org/show_bug.cgi?id=8100

next_timer_interrupt() returns "now" in such a case and causes the code
in tick_nohz_stop_sched_tick() to trigger the timer softirq, which is
bogus as no timer is due for expiry. This results in an endless context
switching between idle and ksoftirqd until a timer is due for expiry.

Modify the hrtimer evaluation so that, it returns now + 1, when the
conversion results in a delta < 1 jiffie. 

It's confirmed to resolve bug #8100

Reported-by: Emil Karlson <[EMAIL PROTECTED]>
Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>

diff --git a/kernel/timer.c b/kernel/timer.c
index 797cccb..440048a 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -695,15 +695,28 @@ static unsigned long cmp_next_hrtimer_event(unsigned long 
now,
 {
        ktime_t hr_delta = hrtimer_get_next_event();
        struct timespec tsdelta;
+       unsigned long delta;
 
        if (hr_delta.tv64 == KTIME_MAX)
                return expires;
 
-       if (hr_delta.tv64 <= TICK_NSEC)
-               return now;
+       /*
+        * Expired timer available, let it expire in the next tick
+        */
+       if (hr_delta.tv64 <= 0)
+               return now + 1;
 
        tsdelta = ktime_to_timespec(hr_delta);
-       now += timespec_to_jiffies(&tsdelta);
+       delta = timespec_to_jiffies(&tsdelta);
+       /*
+        * Take rounding errors in to account and make sure, that it
+        * expires in the next tick. Otherwise we go into an endless
+        * ping pong due to tick_nohz_stop_sched_tick() retriggering
+        * the timer softirq
+        */
+       if (delta < 1)
+               delta = 1;
+       now += delta;
        if (time_before(now, expires))
                return now;
        return expires;


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to