Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2021

kernel-2.6.18-238.el5.src.rpm

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;
 	}