On Sun, Oct 15, 2017 at 16:38 +0000, Joe Gidi wrote:
> >Synopsis:    Recent TSC changes seem to result in frozen clock on Intel NUC
> >Category:    kernel
> >Environment:
>       System      : OpenBSD 6.2
>       Details     : OpenBSD 6.2-current (GENERIC.MP) #148: Fri Oct 13 16:30:01
> MDT 2017
>                        
> dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
> 
>       Architecture: OpenBSD.amd64
>       Machine     : amd64
> >Description:
>       After upgrading to a recent snapshot, I noticed the following line in
> dmesg and a frozen clock once the system was up:
>       acpitimer0: recalibrated TSC frequency -1 Hz
>       I believe this is due to the recent TSC timecounter changes committed by
> mikeb.
> >How-To-Repeat:
>       Happens all the time with current snapshot.
> >Fix:
>       Disabling acpitimer in UKC is enough to bring the system up with a
> functional clock.
> 

Hi,

Thanks for the report.

Please try the patch below and show the resulting dmesg.

diff --git sys/arch/amd64/amd64/tsc.c sys/arch/amd64/amd64/tsc.c
index ce91d5b95df..9ef891dab02 100644
--- sys/arch/amd64/amd64/tsc.c
+++ sys/arch/amd64/amd64/tsc.c
@@ -121,20 +121,21 @@ calculate_tc_delay(struct timecounter *tc, uint64_t 
count1, uint64_t count2)
 uint64_t
 measure_tsc_freq(struct timecounter *tc)
 {
        uint64_t count1, count2, frequency, min_freq, tsc1, tsc2;
        u_long ef;
-       int delay_usec, i, err1, err2, usec;
+       int delay_usec, i, err1, err2, err3, usec;
 
        /* warmup the timers */
        for (i = 0; i < 3; i++) {
                (void)tc->tc_get_timecount(tc);
                (void)rdtsc();
        }
 
        min_freq = ULLONG_MAX;
 
+       err3 = 0;
        delay_usec = 100000;
        for (i = 0; i < 3; i++) {
                ef = read_rflags();
                disable_intr();
 
@@ -148,18 +149,24 @@ measure_tsc_freq(struct timecounter *tc)
                        continue;
 
                usec = calculate_tc_delay(tc, count1, count2);
 
                if ((usec < (delay_usec - RECALIBRATE_DELAY_THRESHOLD)) ||
-                   (usec > (delay_usec + RECALIBRATE_DELAY_THRESHOLD)))
+                   (usec > (delay_usec + RECALIBRATE_DELAY_THRESHOLD))) {
+                       err3++;
                        continue;
+               }
 
                frequency = calculate_tsc_freq(tsc1, tsc2, usec);
 
                min_freq = MIN(min_freq, frequency);
        }
 
+       min_freq = 0;
+       if (err1 || err2)
+               printf("Recalibration err1 %d err2 %d err3 %d\n",
+                   err1, err2, err3);
        return (min_freq);
 }
 
 void
 calibrate_tsc_freq(void)

Reply via email to