tsc: Factor out rdtsc_ordered()
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Mon, 1 Jun 2015 13:41:44 +0000 (21:41 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 4 Jun 2015 03:23:04 +0000 (11:23 +0800)
Use lfence on Intel and mfence on AMD to make sure that all instructions
before rdtsc are completed.

While I'm here
- Remove redundant functions declaration in lwkt_thread.c to unbreak
  compile.
- Add cpu_vendor_id for vkernel64; extra work is needed to set it to a
  proper value.

sys/cpu/i386/include/cpufunc.h
sys/cpu/x86_64/include/cpufunc.h
sys/kern/lwkt_thread.c
sys/platform/pc64/isa/clock.c
sys/platform/vkernel64/include/md_var.h
sys/platform/vkernel64/x86_64/vm_machdep.c

index d4c2d9d..2b00437 100644 (file)
@@ -576,6 +576,21 @@ rdtsc(void)
        return (rv);
 }
 
+#ifdef _KERNEL
+#include <machine/cputypes.h>
+#include <machine/md_var.h>
+
+static __inline u_int64_t
+rdtsc_ordered(void)
+{
+       if (cpu_vendor_id == CPU_VENDOR_INTEL)
+               cpu_lfence();
+       else
+               cpu_mfence();
+       return rdtsc();
+}
+#endif
+
 static __inline void
 wbinvd(void)
 {
index 23806cb..06da913 100644 (file)
@@ -576,6 +576,21 @@ rdtsc(void)
        return (low | ((u_int64_t)high << 32));
 }
 
+#ifdef _KERNEL
+#include <machine/cputypes.h>
+#include <machine/md_var.h>
+
+static __inline u_int64_t
+rdtsc_ordered(void)
+{
+       if (cpu_vendor_id == CPU_VENDOR_INTEL)
+               cpu_lfence();
+       else
+               cpu_mfence();
+       return rdtsc();
+}
+#endif
+
 static __inline void
 wbinvd(void)
 {
index 514af4e..b84b57b 100644 (file)
@@ -100,11 +100,6 @@ int cpu_mwait_spin = 0;
 static void lwkt_schedule_remote(void *arg, int arg2, struct intrframe *frame);
 static void lwkt_setcpu_remote(void *arg);
 
-extern void cpu_heavy_restore(void);
-extern void cpu_lwkt_restore(void);
-extern void cpu_kthread_restore(void);
-extern void cpu_idle_restore(void);
-
 /*
  * We can make all thread ports use the spin backend instead of the thread
  * backend.  This should only be set to debug the spin backend.
index 3413ca8..6a5795b 100644 (file)
@@ -1213,8 +1213,7 @@ tsc_mpsync_test_remote(void *xarg)
        struct tsc_mpsync_arg *arg = xarg;
        uint64_t tsc;
 
-       cpu_lfence();
-       tsc = rdtsc();
+       tsc = rdtsc_ordered();
        if (tsc < arg->tsc_target)
                arg->tsc_mpsync = 0;
 }
@@ -1231,8 +1230,7 @@ tsc_mpsync_test_loop(struct tsc_mpsync_arg *arg)
                    gd->gd_cpuid);
        }
 
-       cpu_lfence();
-       test_begin = rdtsc();
+       test_begin = rdtsc_ordered();
        /* Run test for 100ms */
        test_end = test_begin + (tsc_frequency / 10);
 
@@ -1249,8 +1247,7 @@ tsc_mpsync_test_loop(struct tsc_mpsync_arg *arg)
                lwkt_cpusync_init(&cs, gd->gd_other_cpus,
                    tsc_mpsync_test_remote, arg);
                lwkt_cpusync_interlock(&cs);
-               cpu_lfence();
-               arg->tsc_target = rdtsc();
+               arg->tsc_target = rdtsc_ordered();
                cpu_mfence();
                lwkt_cpusync_deinterlock(&cs);
                crit_exit();
index a1491be..baa50c1 100644 (file)
@@ -75,6 +75,7 @@ extern        vm_offset_t crashdumpmap;
 extern  int    cpu_fxsr;
 
 extern  char    cpu_vendor[];  /* XXX belongs in i386 */
+extern  u_int   cpu_vendor_id; /* XXX belongs in i386 */
 extern  u_int   cpu_id;                /* XXX belongs in i386 */
 
 extern struct vkdisk_info DiskInfo[VKDISK_MAX];
index 61bea28..9a4a687 100644 (file)
@@ -79,6 +79,8 @@ char machine[] = MACHINE;
 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
              machine, 0, "Machine class");
 
+u_int cpu_vendor_id = 0;               /* XXX */
+
 /*
  * Finish a fork operation, with lwp lp2 nearly set up.
  * Copy and update the pcb, set up the stack so that the child