qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] TSC in qem[-kvm] 1.1+ and in-kernel irqchip


From: Michael Tokarev
Subject: [Qemu-devel] TSC in qem[-kvm] 1.1+ and in-kernel irqchip
Date: Thu, 09 Aug 2012 22:27:43 +0400
User-agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:10.0.5) Gecko/20120624 Icedove/10.0.5

As a follow-up to the patch "tsc: use kvmclock for
calibration".

There's another problem reported by several users.
The sympthom is that grub does not show boot menu,
it boots default entry right away without any pause.

After quite some debugging it turned out to be
TSC issue.  Grub uses tsc for its timeout handling.
When setting timeout to some very large value
(10000), I can see the counter is ticking backwards
at a very high speed, ticking from 10000 to 0 in
about 5 seconds.

Running kvm -cpu host,-tsc forces grub to use
rtc clocksource, and the problem goes away.

The most interesting thing is that this is a
problem new for qemu-kvm 1.1 (and is still
present in current git), 1.0 version had no
such issue.  And it only happens when in-kernel
irqchip is enabled -- running with -no-kvm-irqchip
also fixes the grub problem, so that tsc starts
counting "correctly" for grub again.

Gerd mentioned mis-calibration of bios timer
when host is heavily loaded.  I tested grub on
my workstation today which was completely idle,
no other processes running.

It smells like a bug in kvm somewhere.  And it
happens when I explicitly pin kvm to a single
core, so tsc should tick correctly even if its
syncronization is broken between cores.

Current qemu also has this issue (since 1.1),
since it also has in-kernel irqchip support now.

FWIW, here's the TSC calibration routine from
grub:

/* Calibrate the TSC based on the RTC.  */
static void
calibrate_tsc (void)
{
  /* First calibrate the TSC rate (relative, not absolute time). */
  grub_uint64_t start_tsc;
  grub_uint64_t end_tsc;

  start_tsc = grub_get_tsc ();
  grub_pit_wait (0xffff);
  end_tsc = grub_get_tsc ();

  tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0);
}

Thanks,

/mjt



reply via email to

[Prev in Thread] Current Thread [Next in Thread]