On Sat, Sep 03, 2022 at 01:50:28PM +0300, Pavel Korovin wrote:
> After these changes, OpenBSD VMware guest's clock is galloping into the
> future like this:
> Aug 31 02:42:18 build ntpd[55904]: adjusting local clock by -27.085360s
> Aug 31 02:44:26 build ntpd[55904]: adjusting local clock by -116.270573s
> Aug 31 02:47:40 build ntpd[55904]: adjusting local clock by -281.085430s
> Aug 31 02:52:01 build ntpd[55904]: adjusting local clock by -320.064639s
> Aug 31 02:53:09 build ntpd[55904]: adjusting local clock by -385.095886s
> Aug 31 02:54:47 build ntpd[55904]: adjusting local clock by -532.542486s
> Aug 31 02:58:33 build ntpd[55904]: adjusting local clock by -572.363323s
> Aug 31 02:59:38 build ntpd[55904]: adjusting local clock by -655.253598s
> Aug 31 03:01:54 build ntpd[55904]: adjusting local clock by -823.653978s
> Aug 31 03:06:14 build ntpd[55904]: adjusting local clock by -926.705093s
> Aug 31 03:09:00 build ntpd[55904]: adjusting local clock by -1071.837887s
> 
> VM time right after boot:
> rdate -pn $ntp; date
> Sat Sep  3 13:39:43 MSK 2022
> Sat Sep  3 13:43:24 MSK 2022
> 
> $ sysctl -a | grep tsc
> kern.timecounter.hardware=tsc
> kern.timecounter.choice=i8254(0) acpihpet0(1000) tsc(2000)
> acpitimer0(1000)
> machdep.tscfreq=580245275

This frequency looks wrong.

My first guess is that you are hitting a split-read problem in
acpihpet_delay() when recalibrating the TSC.

Does this patch fix it?

If you can't build a kernel for testing I can just commit this and you
can try the snapshot in a day or two.

Index: acpihpet.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpihpet.c,v
retrieving revision 1.28
diff -u -p -r1.28 acpihpet.c
--- acpihpet.c  25 Aug 2022 18:01:54 -0000      1.28
+++ acpihpet.c  6 Sep 2022 16:12:23 -0000
@@ -281,13 +281,19 @@ acpihpet_attach(struct device *parent, s
 void
 acpihpet_delay(int usecs)
 {
-       uint64_t c, s;
+       uint64_t count = 0, cycles;
        struct acpihpet_softc *sc = hpet_timecounter.tc_priv;
+       uint32_t val1, val2;
 
-       s = acpihpet_r(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER);
-       c = usecs * hpet_timecounter.tc_frequency / 1000000;
-       while (acpihpet_r(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER) - s < c)
+       val2 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER);
+       cycles = usecs * hpet_timecounter.tc_frequency / 1000000;
+       while (count < cycles) {
                CPU_BUSY_CYCLE();
+               val1 = val2;
+               val2 = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+                   HPET_MAIN_COUNTER);
+               count += val2 - val1;
+       }
 }
 
 u_int

Reply via email to