Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9501b6cf5541f0d576d566a463f1e7d3eaaab4eb
Commit:     9501b6cf5541f0d576d566a463f1e7d3eaaab4eb
Parent:     317ec6cd00f25d05d153a780bc178c5335f320ee
Author:     Thomas Gleixner <[EMAIL PROTECTED]>
AuthorDate: Sun Mar 25 14:31:17 2007 +0200
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Sun Mar 25 14:57:34 2007 -0700

    [PATCH] dynticks: fix hrtimer rounding error in next_timer_interrupt
    
    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]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 kernel/timer.c |   19 ++++++++++++++++---
 1 files changed, 16 insertions(+), 3 deletions(-)

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 git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to