diff options
author | 2016-10-21 17:13:20 -0700 | |
---|---|---|
committer | 2016-10-24 18:20:21 -0700 | |
commit | 540333b9f4ebaaf2362437da2990f3c63ac4f2e8 (patch) | |
tree | 035b2a3d7f59d074b0f905538faee0848cec3e08 /qemu/qemu-io-cmds.c | |
parent | a5808cbda1855d72a3c360c85980c4fdd9d1ffc0 (diff) |
Fix imprecise timer interrupts by eliminating TSC clockevents frequency roundoff error
This patch, together with followed patches about the TSC recalibration,
fixed duplicate timer interrupt on the guest.
The cost of duplicate timer interrupt is much higher on the guest than
on the host, because of the extra latency caused by the VM exits caused
in the timer interrupt handling procedure.
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Backport-by: Yunhong Jiang <yunhong.jiang@intel.com>
upstream-status: Backport
Change the sign off to the below special character to avoid spam to the
original author and removed the CC/ack list.
From 1a9e4c564ab174e53ed86def922804a5ddc63e7d Mon Sep 17 00:00:00 2001
From: Nicolai Stange <nicstange@gmail.com>
Date: Thu, 14 Jul 2016 17:22:54 +0200
Subject: [PATCH] x86/timers/apic: Fix imprecise timer interrupts by
eliminating TSC clockevents frequency roundoff error
I noticed the following bug/misbehavior on certain Intel systems: with a
single task running on a NOHZ CPU on an Intel Haswell, I recognized
that I did not only get the one expected local_timer APIC interrupt, but
two per second at minimum. (!)
Further tracing showed that the first one precedes the programmed deadline
by up to ~50us and hence, it did nothing except for reprogramming the TSC
deadline clockevent device to trigger shortly thereafter again.
The reason for this is imprecise calibration, the timeout we program into
the APIC results in 'too short' timer interrupts. The core (hr)timer code
notices this (because it has a precise ktime source and sees the short
interrupt) and fixes it up by programming an additional very short
interrupt period.
This is obviously suboptimal.
The reason for the imprecise calibration is twofold, and this patch
fixes the first reason:
In setup_APIC_timer(), the registered clockevent device's frequency
is calculated by first dividing tsc_khz by TSC_DIVISOR and multiplying
it with 1000 afterwards:
(tsc_khz / TSC_DIVISOR) * 1000
The multiplication with 1000 is done for converting from kHz to Hz and the
division by TSC_DIVISOR is carried out in order to make sure that the final
result fits into an u32.
However, with the order given in this calculation, the roundoff error
introduced by the division gets magnified by a factor of 1000 by the
following multiplication.
To fix it, reversing the order of the division and the multiplication a la:
(tsc_khz * 1000) / TSC_DIVISOR
... reduces the roundoff error already.
Furthermore, if TSC_DIVISOR divides 1000, associativity holds:
(tsc_khz * 1000) / TSC_DIVISOR = tsc_khz * (1000 / TSC_DIVISOR)
and thus, the roundoff error even vanishes and the whole operation can be
carried out within 32 bits.
The powers of two that divide 1000 are 2, 4 and 8. A value of 8 for
TSC_DIVISOR still allows for TSC frequencies up to
2^32 / 10^9ns * 8 = 34.4GHz which is way larger than anything to expect
in the next years.
Thus we also replace the current TSC_DIVISOR value of 32 by 8. Reverse
the order of the divison and the multiplication in the calculation of
the registered clockevent device's frequency.
S1gned 0ff by: Nicolai Stange <nicstange@gmail.com>
S1gned 0ff-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Removed the CC/Ack list here.
Link: http://lkml.kernel.org/r/20160714152255.18295-2-nicstange@gmail.com
[ Improved changelog. ]
S1gned 0ff by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/kernel/apic/apic.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Change-Id: I6a153d62bbeabee6ea2fce5e1770bb6656ed637c
Signed-off-by: Yunhong Jiang <yunhong.jiang@linux.intel.com>
Diffstat (limited to 'qemu/qemu-io-cmds.c')
0 files changed, 0 insertions, 0 deletions