On Mon, Mar 28, 2022 at 10:52:09PM -0500, Scott Cheloha wrote:
> 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?

The rest aside, moving the cpu_ucode_apply() call to after the
identifycpu() call is wrong as microcode can add cpuid bits.
I would keep cpu_tsx_disable() before it as well.

I'm sure I've had problems trying to change the sequencing
of lapic, tsc freq and identify in the past.  It caused problems
only on certain machines.

> 
> 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