All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: Michal Piotrowski <michal.k.k.piotrowski@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>,
	David Miller <davem@davemloft.net>, Ingo Molnar <mingo@elte.hu>
Subject: [PATCH] NOHZ: prevent multiplication overflow - stop timer for huge timeouts
Date: Tue, 29 May 2007 23:47:39 +0200	[thread overview]
Message-ID: <1180475259.20546.26.camel@chaos> (raw)
In-Reply-To: <465C222A.8060003@googlemail.com>

get_next_timer_interrupt() returns a delta of (LONG_MAX > 1) in case
there is no timer pending. On 64 bit machines this results in a
multiplication overflow in tick_nohz_stop_sched_tick(). 

Reported by: Dave Miller <davem@davemloft.net>

Make the return value a constant and limit the return value to a 32 bit
value.

When the max timeout value is returned, we can safely stop the tick
timer device. The max jiffies delta results in a 12 days timeout for
HZ=1000.

In the long term the get_next_timer_interrupt() code needs to be
reworked to return ktime instead of jiffies, but we have to wait until
the last users of the original NO_IDLE_HZ code are converted.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

---
 include/linux/timer.h    |    6 ++++++
 kernel/time/tick-sched.c |   16 +++++++++++++++-
 kernel/timer.c           |   10 +++++++++-
 3 files changed, 30 insertions(+), 2 deletions(-)

Index: linux-2.6.21/include/linux/timer.h
===================================================================
--- linux-2.6.21.orig/include/linux/timer.h	2007-05-29 17:58:04.000000000 +0200
+++ linux-2.6.21/include/linux/timer.h	2007-05-29 17:58:06.000000000 +0200
@@ -68,6 +68,12 @@
 extern int mod_timer(struct timer_list *timer, unsigned long expires);
 
 /*
+ * The jiffies value which is added to now, when there is no timer
+ * in the timer wheel:
+ */
+#define NEXT_TIMER_MAX_DELTA	((1UL << 30) - 1)
+
+/*
  * Return when the next timer-wheel timeout occurs (in absolute jiffies),
  * locks the timer base:
  */
Index: linux-2.6.21/kernel/time/tick-sched.c
===================================================================
--- linux-2.6.21.orig/kernel/time/tick-sched.c	2007-05-29 17:58:04.000000000 +0200
+++ linux-2.6.21/kernel/time/tick-sched.c	2007-05-29 17:58:06.000000000 +0200
@@ -233,6 +233,21 @@
 		if (cpu == tick_do_timer_cpu)
 			tick_do_timer_cpu = -1;
 
+		ts->idle_sleeps++;
+
+		/*
+		 * delta_jiffies >= NEXT_TIMER_MAX_DELTA signals that
+		 * there is no timer pending or at least extremly far
+		 * into the future (12 days for HZ=1000). In this case
+		 * we simply stop the tick timer:
+		 */
+		if (unlikely(delta_jiffies >= NEXT_TIMER_MAX_DELTA)) {
+			ts->idle_expires.tv64 = KTIME_MAX;
+			if (ts->nohz_mode == NOHZ_MODE_HIGHRES)
+				hrtimer_cancel(&ts->sched_timer);
+			goto out;
+		}
+
 		/*
 		 * calculate the expiry time for the next timer wheel
 		 * timer
@@ -240,7 +255,6 @@
 		expires = ktime_add_ns(last_update, tick_period.tv64 *
 				       delta_jiffies);
 		ts->idle_expires = expires;
-		ts->idle_sleeps++;
 
 		if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
 			hrtimer_start(&ts->sched_timer, expires,
Index: linux-2.6.21/kernel/timer.c
===================================================================
--- linux-2.6.21.orig/kernel/timer.c	2007-05-29 17:58:05.000000000 +0200
+++ linux-2.6.21/kernel/timer.c	2007-05-29 17:58:06.000000000 +0200
@@ -625,7 +625,7 @@
 static unsigned long __next_timer_interrupt(tvec_base_t *base)
 {
 	unsigned long timer_jiffies = base->timer_jiffies;
-	unsigned long expires = timer_jiffies + (LONG_MAX >> 1);
+	unsigned long expires = timer_jiffies + NEXT_TIMER_MAX_DELTA;
 	int index, slot, array, found = 0;
 	struct timer_list *nte;
 	tvec_t *varray[4];
@@ -708,6 +708,14 @@
 
 	tsdelta = ktime_to_timespec(hr_delta);
 	delta = timespec_to_jiffies(&tsdelta);
+
+	/*
+	 * Limit the delta to the max value, which is checked in
+	 * tick_nohz_stop_sched_tick():
+	 */
+	if (delta > NEXT_TIMER_MAX_DELTA)
+		delta = NEXT_TIMER_MAX_DELTA;
+
 	/*
 	 * Take rounding errors in to account and make sure, that it
 	 * expires in the next tick. Otherwise we go into an endless



  reply	other threads:[~2007-05-29 21:47 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <465C188F.9000900@googlemail.com>
2007-05-29 12:52 ` [3/4] 2.6.22-rc3: known regressions Michal Piotrowski
2007-05-29 21:47   ` Thomas Gleixner [this message]
2007-05-29 23:02     ` [PATCH] NOHZ: prevent multiplication overflow - stop timer for huge timeouts David Miller
2007-05-31  2:33   ` [3/4] 2.6.22-rc3: known regressions Linus Torvalds
2007-05-31  4:51     ` Antonino A. Daplas
2007-05-31  5:54       ` Tero Roponen
2007-05-31  6:04         ` [PATCH] neofb: Fix pseudo_palette array overrun in neofb_setcolreg Antonino A. Daplas
2007-06-05 11:09         ` Antonino A. Daplas
2007-06-05 11:34         ` [PATCH] [RESEND] " Antonino A. Daplas
2007-05-29 12:52 ` [3/4] 2.6.22-rc3: known regressions Michal Piotrowski
2007-05-29 12:53 ` [4/4] " Michal Piotrowski
2007-06-09 11:38   ` Mauro Carvalho Chehab
2007-05-29 12:56 ` [2/4] " Michal Piotrowski
2007-05-29 12:56   ` Michal Piotrowski
2007-05-29 15:01   ` Stephen Hemminger
2007-05-29 15:01     ` Stephen Hemminger
2007-05-31  2:22   ` Linus Torvalds
2007-05-31 22:08     ` Mike Miller (OS Dev)
2007-05-31 22:22       ` Linus Torvalds
2007-05-31 22:39         ` Mike Miller (OS Dev)
2007-05-31 22:50           ` Andrew Morton
2007-05-31 23:12             ` Linus Torvalds
2007-05-31 23:17               ` Roland Dreier
2007-05-31 23:34                 ` Andrew Morton
2007-05-29 12:56 ` Michal Piotrowski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1180475259.20546.26.camel@chaos \
    --to=tglx@linutronix.de \
    --cc=akpm@linux-foundation.org \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michal.k.k.piotrowski@gmail.com \
    --cc=mingo@elte.hu \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.