From: Marcelo Tosatti <mtosatti@redhat.com>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: Frederic Weisbecker <fweisbec@gmail.com>,
Michael Tokarev <mjt@tls.msk.ru>, kvm <kvm@vger.kernel.org>,
Ingo Molnar <mingo@elte.hu>
Subject: [PATCH] tune hrtimer_interrupt hang logic
Date: Sat, 10 Oct 2009 14:32:24 -0300 [thread overview]
Message-ID: <20091010173224.GA5006@amt.cnet> (raw)
In-Reply-To: <alpine.LFD.2.00.0910082217370.9428@localhost.localdomain>
The hrtimer_interrupt hang logic adjusts min_delta_ns based on the
execution time of the hrtimer callbacks.
This is error-prone for virtual machines, where a guest vcpu can be
scheduled out during the execution of the callbacks (and the callbacks
themselves can do operations that translate to blocking operations in
the hypervisor), which in can lead to large min_delta_ns rendering the
system unusable.
Change the logic to simply schedule the next interrupt using the 1/4
ratio, while keeping min_delta_ns intact.
Reported-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index ff037f0..88a8ca5 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -245,6 +245,8 @@ static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer)
#ifdef CONFIG_HIGH_RES_TIMERS
struct clock_event_device;
+extern int hrtimer_interrupt_hang;
+
extern void clock_was_set(void);
extern void hres_timers_resume(void);
extern void hrtimer_interrupt(struct clock_event_device *dev);
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 6d70204..6b81888 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1219,29 +1219,17 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now)
#ifdef CONFIG_HIGH_RES_TIMERS
-static int force_clock_reprogram;
-
/*
* After 5 iteration's attempts, we consider that hrtimer_interrupt()
* is hanging, which could happen with something that slows the interrupt
- * such as the tracing. Then we force the clock reprogramming for each future
- * hrtimer interrupts to avoid infinite loops and use the min_delta_ns
- * threshold that we will overwrite.
+ * such as the tracing.
* The next tick event will be scheduled to 3 times we currently spend on
* hrtimer_interrupt(). This gives a good compromise, the cpus will spend
* 1/4 of their time to process the hrtimer interrupts. This is enough to
* let it running without serious starvation.
*/
+int __read_mostly hrtimer_interrupt_hang;
-static inline void
-hrtimer_interrupt_hanging(struct clock_event_device *dev,
- ktime_t try_time)
-{
- force_clock_reprogram = 1;
- dev->min_delta_ns = (unsigned long)try_time.tv64 * 3;
- printk(KERN_WARNING "hrtimer: interrupt too slow, "
- "forcing clock min delta to %lu ns\n", dev->min_delta_ns);
-}
/*
* High resolution timer interrupt
* Called with interrupts disabled
@@ -1260,8 +1248,27 @@ void hrtimer_interrupt(struct clock_event_device *dev)
retry:
/* 5 retries is enough to notice a hang */
- if (!(++nr_retries % 5))
- hrtimer_interrupt_hanging(dev, ktime_sub(ktime_get(), now));
+ if (!(++nr_retries % 5)) {
+ int tries = 0;
+ ktime_t try_time = ktime_sub(ktime_get(), now);
+
+ if (ktime_to_ns(try_time) < dev->min_delta_ns)
+ try_time = ns_to_ktime(dev->min_delta_ns);
+
+ do {
+ tries++;
+ for (i = 0; i < 3*tries; i++)
+ expires_next = ktime_add(expires_next,try_time);
+
+ printk_once(KERN_WARNING "hrtimer: interrupt too slow, "
+ "scheduling tick %lld ns ahead\n",
+ ktime_to_ns(ktime_sub(expires_next,
+ ktime_get())));
+ } while (tick_program_event(expires_next, 1));
+
+ hrtimer_interrupt_hang++;
+ return;
+ }
now = ktime_get();
@@ -1327,7 +1334,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
/* Reprogramming necessary ? */
if (expires_next.tv64 != KTIME_MAX) {
- if (tick_program_event(expires_next, force_clock_reprogram))
+ if (tick_program_event(expires_next, 0))
goto retry;
}
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 0d949c5..7223853 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1032,6 +1032,17 @@ static struct ctl_table kern_table[] = {
.proc_handler = &proc_dointvec,
},
#endif
+#ifdef CONFIG_HIGH_RES_TIMERS
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "hrtimer_interrupt_hang",
+ .data = &hrtimer_interrupt_hang,
+ .maxlen = sizeof (int),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+
+ },
+#endif
/*
* NOTE: do not add new entries to this table unless you have read
* Documentation/sysctl/ctl_unnumbered.txt
next prev parent reply other threads:[~2009-10-10 17:33 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-09-29 13:12 kvm guest: hrtimer: interrupt too slow Michael Tokarev
2009-09-29 13:47 ` Avi Kivity
2009-09-29 13:58 ` Michael Tokarev
2009-10-05 10:47 ` Avi Kivity
2009-10-03 23:12 ` Marcelo Tosatti
[not found] ` <4AC88E7E.8050909@msgid.tls.msk.ru>
2009-10-05 0:50 ` Marcelo Tosatti
2009-10-05 9:31 ` Michael Tokarev
2009-10-06 13:30 ` Michael Tokarev
2009-10-07 23:17 ` Frederic Weisbecker
2009-10-08 0:54 ` Marcelo Tosatti
2009-10-08 7:54 ` Michael Tokarev
2009-10-08 8:06 ` Thomas Gleixner
2009-10-08 8:14 ` Michael Tokarev
2009-10-08 9:29 ` Thomas Gleixner
2009-10-08 14:06 ` Michael Tokarev
2009-10-08 15:06 ` Thomas Gleixner
2009-10-08 19:52 ` Marcelo Tosatti
2009-10-09 21:22 ` Michael Tokarev
2009-10-09 22:27 ` Frederic Weisbecker
2009-10-09 22:34 ` Michael Tokarev
2009-10-10 9:18 ` Michael Tokarev
2009-10-10 9:24 ` Frederic Weisbecker
2009-10-10 17:37 ` Marcelo Tosatti
2009-10-08 8:05 ` Thomas Gleixner
2009-10-08 19:22 ` Marcelo Tosatti
2009-10-08 20:25 ` Thomas Gleixner
2009-10-08 21:02 ` Michael Tokarev
2009-10-10 17:32 ` Marcelo Tosatti [this message]
2009-10-08 8:09 ` Michael Tokarev
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=20091010173224.GA5006@amt.cnet \
--to=mtosatti@redhat.com \
--cc=fweisbec@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=mjt@tls.msk.ru \
--cc=tglx@linutronix.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).