Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174338778
D60233.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D60233.diff
View Options
diff --git a/sys/amd64/vmm/io/vrtc.c b/sys/amd64/vmm/io/vrtc.c
--- a/sys/amd64/vmm/io/vrtc.c
+++ b/sys/amd64/vmm/io/vrtc.c
@@ -80,6 +80,7 @@
u_int addr; /* RTC register to read or write */
sbintime_t base_uptime;
time_t base_rtctime;
+ sbintime_t callout_time;
struct rtcdev rtcdev;
};
@@ -520,8 +521,9 @@
}
static void
-vrtc_callout_reset(struct vrtc *vrtc, sbintime_t freqsbt)
+vrtc_callout_reset(struct vrtc *vrtc, sbintime_t freqsbt, bool periodic)
{
+ sbintime_t now;
KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
@@ -533,8 +535,20 @@
return;
}
VM_CTR1(vrtc->vm, "RTC callout frequency %d hz", SBT_1S / freqsbt);
- callout_reset_sbt(&vrtc->callout, freqsbt, 0, vrtc_callout_handler,
- vrtc, 0);
+
+ /*
+ * From the handler, the next deadline is one period after the previous
+ * one, not one period after the handler ran: else the latency of each
+ * callout adds up and the interrupt comes at a lower rate than the
+ * guest programmed. Start afresh if that deadline has passed.
+ */
+ now = sbinuptime();
+ if (periodic)
+ vrtc->callout_time += freqsbt;
+ if (!periodic || vrtc->callout_time < now)
+ vrtc->callout_time = now + freqsbt;
+ callout_reset_sbt(&vrtc->callout, vrtc->callout_time, 0,
+ vrtc_callout_handler, vrtc, C_ABSOLUTE);
}
static void
@@ -571,7 +585,7 @@
freqsbt = vrtc_freq(vrtc);
KASSERT(freqsbt != 0, ("%s: vrtc frequency cannot be zero", __func__));
- vrtc_callout_reset(vrtc, freqsbt);
+ vrtc_callout_reset(vrtc, freqsbt, true);
done:
VRTC_UNLOCK(vrtc);
}
@@ -690,7 +704,7 @@
*/
newfreq = vrtc_freq(vrtc);
if (newfreq != oldfreq)
- vrtc_callout_reset(vrtc, newfreq);
+ vrtc_callout_reset(vrtc, newfreq, false);
else
vrtc_callout_check(vrtc, newfreq);
@@ -742,7 +756,7 @@
*/
newfreq = vrtc_freq(vrtc);
if (newfreq != oldfreq)
- vrtc_callout_reset(vrtc, newfreq);
+ vrtc_callout_reset(vrtc, newfreq, false);
else
vrtc_callout_check(vrtc, newfreq);
}
@@ -1066,7 +1080,7 @@
SNAPSHOT_BUF_OR_LEAVE(vrtc->rtcdev.nvram2, sizeof(vrtc->rtcdev.nvram2),
meta, ret, done);
- vrtc_callout_reset(vrtc, vrtc_freq(vrtc));
+ vrtc_callout_reset(vrtc, vrtc_freq(vrtc), false);
done:
VRTC_UNLOCK(vrtc);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 3, 12:44 PM (12 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40124080
Default Alt Text
D60233.diff (2 KB)
Attached To
Mode
D60233: vmm: do not let the RTC's periodic interrupt drift
Attached
Detach File
Event Timeline
Log In to Comment