Hello tech@,

This diff attaches pvclock with lower priority (500) in case of unstable
tsc (PVCLOCK_FLAG_TSC_STABLE) instead of not attaching at all.

For reference current priorities,
tsc (variant)          : -2000
i8254                  : 0
acpitimer              : 1000
acpihpet0              : 1000
pvclock (stable tsc)   : 1500
tsc (invariant, stable): 2000

--
Pratik

Index: sys/dev/pv/pvclock.c
===================================================================
RCS file: /home/cvs/src/sys/dev/pv/pvclock.c,v
retrieving revision 1.4
diff -u -p -a -u -r1.4 pvclock.c
--- sys/dev/pv/pvclock.c        13 May 2019 15:40:34 -0000      1.4
+++ sys/dev/pv/pvclock.c        25 Nov 2019 06:49:09 -0000
@@ -29,11 +29,14 @@
#include <sys/atomic.h>

#include <machine/cpu.h>
+#include <machine/atomic.h>
#include <uvm/uvm_extern.h>

#include <dev/pv/pvvar.h>
#include <dev/pv/pvreg.h>

+uint pvclock_lastcount;
+
struct pvclock_softc {
        struct device            sc_dev;
        void                    *sc_time;
@@ -141,21 +144,22 @@ pvclock_attach(struct device *parent, st
                flags = ti->ti_flags;
        } while (!pvclock_read_done(ti, version));

-       if ((flags & PVCLOCK_FLAG_TSC_STABLE) == 0) {
-               wrmsr(KVM_MSR_SYSTEM_TIME, pa & ~PVCLOCK_SYSTEM_TIME_ENABLE);
-               km_free(sc->sc_time, PAGE_SIZE, &kv_any, &kp_zero);
-               printf(": unstable clock\n");
-               return;
-       }
-
        sc->sc_tc = &pvclock_timecounter;
        sc->sc_tc->tc_name = DEVNAME(sc);
        sc->sc_tc->tc_frequency = 1000000000ULL;
        sc->sc_tc->tc_priv = sc;

+       pvclock_lastcount = 0;
+
        /* Better than HPET but below TSC */
        sc->sc_tc->tc_quality = 1500;

+       if ((flags & PVCLOCK_FLAG_TSC_STABLE) == 0) {
+               /* if tsc is not stable, set a lower priority */
+               /* Better than i8254 but below HPET */
+               sc->sc_tc->tc_quality = 500;
+       }
+
        tc_init(sc->sc_tc);

        printf("\n");
@@ -216,10 +220,6 @@ pvclock_get_timecount(struct timecounter
                flags = ti->ti_flags;
        } while (!pvclock_read_done(ti, version));

-       /* This bit must be set as we attached based on the stable flag */
-       if ((flags & PVCLOCK_FLAG_TSC_STABLE) == 0)
-               panic("%s: unstable result on stable clock", DEVNAME(sc));
-
        /*
         * The algorithm is described in
         * linux/Documentation/virtual/kvm/msr.txt
@@ -230,6 +230,14 @@ pvclock_get_timecount(struct timecounter
        else
                delta <<= shift;
        ctr = ((delta * mul_frac) >> 32) + system_time;
+
+       if ((flags & PVCLOCK_FLAG_TSC_STABLE) != 0)
+               return (ctr);
+
+       if (ctr < pvclock_lastcount)
+               return (pvclock_lastcount);
+
+       atomic_swap_uint(&pvclock_lastcount, ctr);

        return (ctr);
}

Reply via email to