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
>
> [email protected]:/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)