Re: kvm very slow

Ulrich Schreiner
2007-08-08T06:28:52Z

ok,

patched kvm-33, compile, install

i started qemu-system-x86_64 with "-no-rtc -use-hpet" and ... well the
time drift is unchanged. ok, the warning for "dev.rtc..." has gone.

doing a date (guest) gives me (for example):

8:08:59

after 10 (real!) seconds, date (guest) gives me

8:09:04

--> 10 real seconds are about 5 seconds in the guest. working about 5
minutes in the guest and the clock drifts a few minutes in the past.

</usc>

ps: the line

"-use-rtc use /dev/hpet (HPET) for timer alarm (do use
gettimeofday)\n"

should be

"-use-hpet use /dev/hpet (HPET) for timer alarm (do use
gettimeofday)\n"

because "use-hpet" is the option which is aksed in the code

Am Dienstag, den 07.08.2007, 22:49 +0200 schrieb Luca Tettamanti:
> Il Tue, Aug 07, 2007 at 02:08:08PM +0200, Luca ha scritto:
> > On 8/7/07, Dor Laor <dor.laor-atKUWr5tajBWk0Htik3J/w@public.gmane.org> wrote:
> > > Luca claims the HPET intefer the RTC. Can it be disabled? ( I know some
> > > new chipsets implement rtc using HPET).
> >
> > Basically HPET can operate in legacy mode - where it uses the same IRQ
> > as the RTC (and RTC won't deliver any interrupt) - or in "standard"
> > mode where the IO-APIC can be configured to deliver the interrupt on
> > any line. ATM Linux can only use the legacy mode.
> > You can of course disable HPET, but then it won't be available for
> > in-kernel timekeeping (in case e.g. the TSC is not stable/synced). I'd
> > rather add support for HPET as timer in QEMU...
>
> Something like this. Ulrich can you give it a try:
>
> ---
> Patch against current GIT, but also applies to kvm-33.
> Run kvm with -use-hpet.
>
> qemu/vl.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 60 insertions(+), 2 deletions(-)
>
> diff --git a/qemu/vl.c b/qemu/vl.c
> index 4ad39f1..36628af 100644
> --- a/qemu/vl.c
> +++ b/qemu/vl.c
> @@ -54,6 +54,7 @@
> #include <pty.h>
> #include <malloc.h>
> #include <linux/rtc.h>
> +#include <linux/hpet.h>
> #include <linux/ppdev.h>
> #endif
> #endif
> @@ -996,8 +997,9 @@ static void host_alarm_handler(int host_signum)
>
> static int use_rtc = 1;
> static int rtc_fd;
> +static int use_hpet;
>
> -static int start_rtc_timer(void)
> +static int enable_rtc(void)
> {
> rtc_fd = open("/dev/rtc", O_RDONLY);
> if (rtc_fd < 0)
> @@ -1017,6 +1019,56 @@ static int start_rtc_timer(void)
> return 0;
> }
>
> +static char default_hpet[] = "/dev/hpet";
> +
> +static int enable_hpet(void)
> +{
> + struct hpet_info info;
> + int r;
> +
> + rtc_fd = open(default_hpet, O_RDONLY);
> + if (rtc_fd < 0)
> + return -1;
> +
> + /* Set frequency */
> + r = ioctl(rtc_fd, HPET_IRQFREQ, RTC_FREQ);
> + if (r < 0) {
> + fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024 Hz timer. This is not a fatal\n"
> + "error, but for better emulation accuracy type:\n"
> + "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
> + goto fail;
> + }
> +
> + /* Check capabilities */
> + r = ioctl(rtc_fd, HPET_INFO, &info);
> + if (r < 0)
> + goto fail;
> +
> + /* Enable peridic mode */
> + r = ioctl(rtc_fd, HPET_EPI, 0);
> + if (info.hi_flags && (r < 0))
> + goto fail;
> +
> + /* Enable interrupt */
> + r = ioctl(rtc_fd, HPET_IE_ON, 0);
> + if (r < 0)
> + goto fail;
> +
> + pit_min_timer_count = PIT_FREQ / RTC_FREQ;
> +
> + return 0;
> +fail:
> + close(rtc_fd);
> + return -1;
> +}
> +
> +static int start_rtc_timer(void)
> +{
> + if (use_hpet)
> + return enable_hpet();
> + else
> + return enable_rtc();
> +}
> #else
>
> static int start_rtc_timer(void)
> @@ -1090,7 +1142,7 @@ static void init_timer_alarm(void)
> 2.6 kernels */
> if (itv.it_interval.tv_usec > 1000 || 1) {
> /* try to use /dev/rtc to have a faster timer */
> - if (!use_rtc || (start_rtc_timer() < 0))
> + if ((!use_rtc && !use_hpet) || (start_rtc_timer() < 0))
> goto use_itimer;
> /* disable itimer */
> itv.it_interval.tv_sec = 0;
> @@ -6482,6 +6534,7 @@ void help(void)
> "-tdf inject timer interrupts that got lost\n"
> #if defined(__linux__)
> "-no-rtc don't use /dev/rtc for timer alarm (do use gettimeofday)\n"
> + "-use-rtc use /dev/hpet (HPET) for timer alarm (do use gettimeofday)\n"
> #endif
> "-option-rom rom load a file, rom, into the option ROM space\n"
> "\n"
> @@ -6574,6 +6627,7 @@ enum {
> QEMU_OPTION_tdf,
> #if defined(__linux__)
> QEMU_OPTION_no_rtc,
> + QEMU_OPTION_use_hpet,
> #endif
> QEMU_OPTION_cpu_vendor,
> };
> @@ -6671,6 +6725,7 @@ const QEMUOption qemu_options[] = {
> { "tdf", 0, QEMU_OPTION_tdf }, /* enable time drift fix */
> #if defined(__linux__)
> { "no-rtc", 0, QEMU_OPTION_no_rtc },
> + { "use-hpet", 0, QEMU_OPTION_use_hpet },
> #endif
> { "cpu-vendor", HAS_ARG, QEMU_OPTION_cpu_vendor },
> { NULL },
> @@ -7395,6 +7450,9 @@ int main(int argc, char **argv)
> case QEMU_OPTION_no_rtc:
> use_rtc = 0;
> break;
> + case QEMU_OPTION_use_hpet:
> + use_hpet = 1;
> + break;
> #endif
> case QEMU_OPTION_cpu_vendor:
> cpu_vendor_string = optarg;
>
>
>
> Luca