From: Hans-Joachim Picht <hpicht@redhat.com> Date: Wed, 12 Nov 2008 14:27:34 +0100 Subject: [misc] lots of interrupts with /proc/.../hz_timer=0 Message-id: 20081112132734.GB11656@blc4eb509856389.ibm.com O-Subject: [RHEL5 U4 PATCH 1/1] high number of interrupts with /proc/sys/kernel/hz_timer = 0 Bugzilla: 470289 RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com> RH-Acked-by: Rik van Riel <riel@redhat.com> RH-Acked-by: Prarit Bhargava <prarit@redhat.com> Description ============ There is a problem with the high resolution timer code that can cause lots of timer interrupts if /proc/sys/kernel/hz_timer = 0. This happens if a cpu is going idle and finds that there is a high resolution timer that is not expired but pending before the next timer tick. The cpu idle loop calls next_timer_event() to get the wake up time in jiffies. next_timer_event() calls hrtimer_get_next_event() which will return a wake up time in nanoseconds. For the problematic case this returns a value smaller than NSEC_PER_TICK. This gets converted to 0 jiffies wait time which causes the idle process to wakeup immediately after it went to sleep. The timer interrupt code checks the high resolution timer lists and finds the pending timer which may or may not be expired now. If it is not expired yet the above repeats until the timer is finally expired. This causes high cpu load on an idle system and one symptom is a high EXT interrupt count in the output of /proc/interrupts. Bugzilla ========= BZ 470289 https://bugzilla.redhat.com/show_bug.cgi?id=470289 Upstream status of the patch: ============================= The upstream code base is not affected by this problem and therefor the patch has not been posted upstream. Test status: ============ The patch has been tested and fixes the problem. The fix has been verified by the IBM test department. Please ACK. With best regards, --Hans diff --git a/kernel/timer.c b/kernel/timer.c index 567eea3..bafef95 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -613,6 +613,8 @@ unsigned long next_timer_interrupt(void) struct timespec tsdelta; tsdelta = ktime_to_timespec(hr_delta); hr_expires = timespec_to_jiffies(&tsdelta); + if (hr_expires < 1) + hr_expires = 1; if (hr_expires < 3) return hr_expires + jiffies; }