From: Marcelo Tosatti <mtosatti@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: Alex Williamson <alex.williamson@redhat.com>,
Xiao Guangrong <guangrong.xiao@gmail.com>,
qemu-devel <qemu-devel@nongnu.org>,
Vadim Rozenfeld <vrozenfe@redhat.com>
Subject: Re: [PATCH v2] mc146818rtc: fix timer interrupt reinjection
Date: Mon, 18 Nov 2019 19:44:30 -0200 [thread overview]
Message-ID: <20191118214428.GA15341@amt.cnet> (raw)
In-Reply-To: <3ba4e29d-3436-9d7b-ebc0-5e1ae566e760@redhat.com>
On Sun, Nov 17, 2019 at 11:12:43AM +0100, Paolo Bonzini wrote:
> On 17/11/19 05:31, Alex Williamson wrote:
> > The 'merge' option gives me a similar error. The 'delay' option is
> > the only other choice where I can actually start the VM, but this
> > results in the commandline:
> >
> > -rtc base=localtime
> >
> > (no driftfix specified)
>
> none is the default, so that's okay.
>
> > This does appear to resolve the issue, but of course compatibility
> > with existing configurations has regressed. Thanks,
>
> Yeah, I guess this was just a suggestion to double-check the cause of
> the regression.
>
> The problem could be that periodic_timer_update is using old_period == 0
> for two cases: no period change, and old period was 0 (periodic timer
> off).
> Something like the following distinguishes the two cases by always using
> s->period (currently it was only used for driftfix=slew) and passing
> s->period instead of 0 when there is no period change.
>
> More cleanups are possible, but this is the smallest patch that implements
> the idea. The first patch is big but, indentation changes aside, it's
> moving a single closed brace.
>
> Alex/Marcelo, can you check if it fixes both of your test cases?
Second patch blocks NTPd from synchronizing to a source at all
(can't even confirm if it fails to synchronize after a while).
Problem seems to be that calling from timer interrupt path:
/*
* if the periodic timer's update is due to period re-configuration,
* we should count the clock since last interrupt.
*/
if (old_period) {
int64_t last_periodic_clock, next_periodic_clock;
next_periodic_clock = muldiv64(s->next_periodic_time,
RTC_CLOCK_RATE, NANOSECONDS_PER_SECOND);
last_periodic_clock = next_periodic_clock - old_period;
lost_clock = cur_clock - last_periodic_clock;
assert(lost_clock >= 0);
}
Adds the difference between when the timer interrupt actually executed
(cur_clock) and when it should have executed (last_periodic_clock)
as reinject time (which will end up injecting more timer interrupts
than necessary, so the clock runs faster than it should).
Perhaps this is the reason for the 5%+ performance delta?
The following, on top of Paolo's two patches, fixes it for me
(and NTPd is able to maintain clock synchronized while playing video on Windows 7).
Alex perhaps you can give it a try?
--- hw/rtc/mc146818rtc.c.orig 2019-11-18 19:16:49.077479836 -0200
+++ hw/rtc/mc146818rtc.c 2019-11-18 19:22:35.706803090 -0200
@@ -168,7 +168,7 @@
* is just due to period adjustment.
*/
static void
-periodic_timer_update(RTCState *s, int64_t current_time, uint32_t old_period)
+periodic_timer_update(RTCState *s, int64_t current_time, uint32_t old_period, bool period_change)
{
uint32_t period;
int64_t cur_clock, next_irq_clock, lost_clock = 0;
@@ -190,7 +190,7 @@
* if the periodic timer's update is due to period re-configuration,
* we should count the clock since last interrupt.
*/
- if (old_period) {
+ if (old_period && period_change) {
int64_t last_periodic_clock, next_periodic_clock;
next_periodic_clock = muldiv64(s->next_periodic_time,
@@ -246,7 +246,7 @@
{
RTCState *s = opaque;
- periodic_timer_update(s, s->next_periodic_time, s->period);
+ periodic_timer_update(s, s->next_periodic_time, s->period, false);
s->cmos_data[RTC_REG_C] |= REG_C_PF;
if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
@@ -512,7 +512,7 @@
if (update_periodic_timer) {
periodic_timer_update(s, qemu_clock_get_ns(rtc_clock),
- old_period);
+ old_period, true);
}
check_update_timer(s);
@@ -551,7 +551,7 @@
if (update_periodic_timer) {
periodic_timer_update(s, qemu_clock_get_ns(rtc_clock),
- old_period);
+ old_period, true);
}
check_update_timer(s);
@@ -805,7 +805,7 @@
uint64_t now = qemu_clock_get_ns(rtc_clock);
if (now < s->next_periodic_time ||
now > (s->next_periodic_time + get_max_clock_jump())) {
- periodic_timer_update(s, qemu_clock_get_ns(rtc_clock), s->period);
+ periodic_timer_update(s, qemu_clock_get_ns(rtc_clock), s->period, false);
}
}
next prev parent reply other threads:[~2019-11-18 21:49 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-10 12:30 [PATCH v2] mc146818rtc: fix timer interrupt reinjection Marcelo Tosatti
2019-10-10 12:35 ` Paolo Bonzini
2019-10-24 11:22 ` Philippe Mathieu-Daudé
2019-10-24 12:08 ` Philippe Mathieu-Daudé
2019-11-16 20:58 ` Alex Williamson
2019-11-17 3:20 ` Marcelo Tosatti
2019-11-17 4:31 ` Alex Williamson
2019-11-17 10:12 ` Paolo Bonzini
2019-11-17 18:32 ` Alex Williamson
2019-11-18 21:44 ` Marcelo Tosatti [this message]
2019-11-18 22:08 ` Paolo Bonzini
2019-11-18 23:28 ` Alex Williamson
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=20191118214428.GA15341@amt.cnet \
--to=mtosatti@redhat.com \
--cc=alex.williamson@redhat.com \
--cc=guangrong.xiao@gmail.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=vrozenfe@redhat.com \
/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).