From: Dor Laor <dor.laor@qumranet.com>
To: Gleb Natapov <gleb@qumranet.com>
Cc: kvm@vger.kernel.org, qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [PATCH 2/3] Fix time drift problem under high load when PIT is in use.
Date: Sun, 29 Jun 2008 23:56:22 +0300 [thread overview]
Message-ID: <1214772982.782.97.camel@localhost.localdomain> (raw)
In-Reply-To: <20080629135917.5447.7163.stgit@gleb-debian.qumranet.com.qumranet.com>
On Sun, 2008-06-29 at 16:59 +0300, Gleb Natapov wrote:
> Count the number of interrupts that was lost due to interrupt coalescing
> and re-inject them back when possible. This fixes time drift problem when
> pit is used as a time source.
>
> Signed-off-by: Gleb Natapov <gleb@qumranet.com>
> ---
>
> hw/i8254.c | 20 +++++++++++++++++++-
> 1 files changed, 19 insertions(+), 1 deletions(-)
>
> diff --git a/hw/i8254.c b/hw/i8254.c
> index 4813b03..c4f0f46 100644
> --- a/hw/i8254.c
> +++ b/hw/i8254.c
> @@ -61,6 +61,8 @@ static PITState pit_state;
>
> static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
>
> +static uint32_t pit_irq_coalesced;
The pit has 3 channels, it should be a channel field.
Also every time the pit frequency changes the above field should be
compensated with * (new_freq/old_freq).
For example, if the guest was running with 1000hz clock and the
pit_irq_coalesced value is 100 currently, a frequency change to 100hz
should reduce pit_irq_coalesced to 10.
Except that, its high time we stop drifting :)
> +
> static int pit_get_count(PITChannelState *s)
> {
> uint64_t d;
> @@ -369,12 +371,28 @@ static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
> return;
> expire_time = pit_get_next_transition_time(s, current_time);
> irq_level = pit_get_out1(s, current_time);
> - qemu_set_irq(s->irq, irq_level);
> + if(irq_level) {
> + if(!qemu_irq_raise(s->irq))
> + pit_irq_coalesced++;
> + } else {
> + qemu_irq_lower(s->irq);
> + if(pit_irq_coalesced > 0) {
> + if(qemu_irq_raise(s->irq))
> + pit_irq_coalesced--;
> + qemu_irq_lower(s->irq);
> + }
> + }
> +
> #ifdef DEBUG_PIT
> printf("irq_level=%d next_delay=%f\n",
> irq_level,
> (double)(expire_time - current_time) / ticks_per_sec);
> #endif
> + if(pit_irq_coalesced && expire_time != -1) {
> + uint32_t div = ((pit_irq_coalesced >> 10) & 0x7f) + 2;
> + expire_time -= ((expire_time - current_time) / div);
> + }
> +
> s->next_transition_time = expire_time;
> if (expire_time != -1)
> qemu_mod_timer(s->irq_timer, expire_time);
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
WARNING: multiple messages have this Message-ID (diff)
From: Dor Laor <dor.laor@qumranet.com>
To: Gleb Natapov <gleb@qumranet.com>
Cc: qemu-devel <qemu-devel@nongnu.org>, kvm@vger.kernel.org
Subject: [Qemu-devel] Re: [PATCH 2/3] Fix time drift problem under high load when PIT is in use.
Date: Sun, 29 Jun 2008 23:56:22 +0300 [thread overview]
Message-ID: <1214772982.782.97.camel@localhost.localdomain> (raw)
In-Reply-To: <20080629135917.5447.7163.stgit@gleb-debian.qumranet.com.qumranet.com>
On Sun, 2008-06-29 at 16:59 +0300, Gleb Natapov wrote:
> Count the number of interrupts that was lost due to interrupt coalescing
> and re-inject them back when possible. This fixes time drift problem when
> pit is used as a time source.
>
> Signed-off-by: Gleb Natapov <gleb@qumranet.com>
> ---
>
> hw/i8254.c | 20 +++++++++++++++++++-
> 1 files changed, 19 insertions(+), 1 deletions(-)
>
> diff --git a/hw/i8254.c b/hw/i8254.c
> index 4813b03..c4f0f46 100644
> --- a/hw/i8254.c
> +++ b/hw/i8254.c
> @@ -61,6 +61,8 @@ static PITState pit_state;
>
> static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
>
> +static uint32_t pit_irq_coalesced;
The pit has 3 channels, it should be a channel field.
Also every time the pit frequency changes the above field should be
compensated with * (new_freq/old_freq).
For example, if the guest was running with 1000hz clock and the
pit_irq_coalesced value is 100 currently, a frequency change to 100hz
should reduce pit_irq_coalesced to 10.
Except that, its high time we stop drifting :)
> +
> static int pit_get_count(PITChannelState *s)
> {
> uint64_t d;
> @@ -369,12 +371,28 @@ static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
> return;
> expire_time = pit_get_next_transition_time(s, current_time);
> irq_level = pit_get_out1(s, current_time);
> - qemu_set_irq(s->irq, irq_level);
> + if(irq_level) {
> + if(!qemu_irq_raise(s->irq))
> + pit_irq_coalesced++;
> + } else {
> + qemu_irq_lower(s->irq);
> + if(pit_irq_coalesced > 0) {
> + if(qemu_irq_raise(s->irq))
> + pit_irq_coalesced--;
> + qemu_irq_lower(s->irq);
> + }
> + }
> +
> #ifdef DEBUG_PIT
> printf("irq_level=%d next_delay=%f\n",
> irq_level,
> (double)(expire_time - current_time) / ticks_per_sec);
> #endif
> + if(pit_irq_coalesced && expire_time != -1) {
> + uint32_t div = ((pit_irq_coalesced >> 10) & 0x7f) + 2;
> + expire_time -= ((expire_time - current_time) / div);
> + }
> +
> s->next_transition_time = expire_time;
> if (expire_time != -1)
> qemu_mod_timer(s->irq_timer, expire_time);
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2008-06-29 20:57 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-29 13:59 [PATCH 0/3] Fix guest time drift under heavy load Gleb Natapov
2008-06-29 13:59 ` [PATCH 1/3] Change qemu_set_irq() to return status information Gleb Natapov
2008-06-29 13:59 ` [PATCH 2/3] Fix time drift problem under high load when PIT is in use Gleb Natapov
2008-06-29 20:56 ` Dor Laor [this message]
2008-06-29 20:56 ` [Qemu-devel] " Dor Laor
2008-06-29 13:59 ` [PATCH 3/3] Fix time drift problem under high load when RTC " Gleb Natapov
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=1214772982.782.97.camel@localhost.localdomain \
--to=dor.laor@qumranet.com \
--cc=gleb@qumranet.com \
--cc=kvm@vger.kernel.org \
--cc=qemu-devel@nongnu.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.