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)