I want to use the IA32_TSC_ADJUST MSR where available when testing TSC
synchronization.  We note if it's available during CPU identification.

Can we do CPU identification earlier in cpu_hatch() and
cpu_start_secondary(), before we do the TSC sync testing?

This can wait until after release.  I'm just trying to suss out
whether there is an order dependency I'm not seeing.  My laptop
appears to boot and resume no differently with this patch.

Thoughts?

Index: cpu.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/cpu.c,v
retrieving revision 1.155
diff -u -p -r1.155 cpu.c
--- cpu.c       21 Feb 2022 11:03:39 -0000      1.155
+++ cpu.c       29 Mar 2022 03:49:31 -0000
@@ -842,20 +842,7 @@ cpu_start_secondary(struct cpu_info *ci)
                printf("dropping into debugger; continue from here to resume 
boot\n");
                db_enter();
 #endif
-       } else {
-               /*
-                * Synchronize time stamp counters. Invalidate cache and
-                * synchronize twice (in tsc_sync_bp) to minimize possible
-                * cache effects. Disable interrupts to try and rule out any
-                * external interference.
-                */
-               s = intr_disable();
-               wbinvd();
-               tsc_sync_bp(ci);
-               intr_restore(s);
-#ifdef TSC_DEBUG
-               printf("TSC skew=%lld\n", (long long)ci->ci_tsc_skew);
-#endif
+               goto cleanup;
        }
 
        if ((ci->ci_flags & CPUF_IDENTIFIED) == 0) {
@@ -865,11 +852,28 @@ cpu_start_secondary(struct cpu_info *ci)
                for (i = 2000000; (ci->ci_flags & CPUF_IDENTIFY) && i > 0; i--)
                        delay(10);
 
-               if (ci->ci_flags & CPUF_IDENTIFY)
+               if (ci->ci_flags & CPUF_IDENTIFY) {
                        printf("%s: failed to identify\n",
                            ci->ci_dev->dv_xname);
+                       goto cleanup;
+               }
        }
 
+       /*
+        * Synchronize time stamp counters. Invalidate cache and
+        * synchronize twice (in tsc_sync_bp) to minimize possible
+        * cache effects. Disable interrupts to try and rule out any
+        * external interference.
+        */
+       s = intr_disable();
+       wbinvd();
+       tsc_sync_bp(ci);
+       intr_restore(s);
+#ifdef TSC_DEBUG
+       printf("TSC skew=%lld\n", (long long)ci->ci_tsc_skew);
+#endif
+
+cleanup:
        CPU_START_CLEANUP(ci);
 
        pmap_kremove(MP_TRAMPOLINE, PAGE_SIZE);
@@ -930,20 +934,7 @@ cpu_hatch(void *v)
        if (ci->ci_flags & CPUF_PRESENT)
                panic("%s: already running!?", ci->ci_dev->dv_xname);
 #endif
-
-       /*
-        * Synchronize the TSC for the first time. Note that interrupts are
-        * off at this point.
-        */
-       wbinvd();
        ci->ci_flags |= CPUF_PRESENT;
-       ci->ci_tsc_skew = 0;    /* reset on resume */
-       tsc_sync_ap(ci);
-
-       lapic_enable();
-       lapic_startclock();
-       cpu_ucode_apply(ci);
-       cpu_tsx_disable(ci);
 
        if ((ci->ci_flags & CPUF_IDENTIFIED) == 0) {
                /*
@@ -960,6 +951,19 @@ cpu_hatch(void *v)
                /* Prevent identifycpu() from running again */
                atomic_setbits_int(&ci->ci_flags, CPUF_IDENTIFIED);
        }
+
+       /*
+        * Synchronize the TSC for the first time. Note that interrupts are
+        * off at this point.
+        */
+       wbinvd();
+       ci->ci_tsc_skew = 0;    /* reset on resume */
+       tsc_sync_ap(ci);
+
+       lapic_enable();
+       lapic_startclock();
+       cpu_ucode_apply(ci);
+       cpu_tsx_disable(ci);
 
        while ((ci->ci_flags & CPUF_GO) == 0)
                delay(10);

Reply via email to