«前の日(03-18) 最新 次の日(03-20)» 追記

meta's blog - The Power To Serve

筆者について - No Unix, No Life

日本xrdpユーザ会発起人。

とある元大学院生の UNIX 系日記。FreeBSDを通じてOSSに囁かな貢献を。 FreeBSD ports committer やってます。

HTTPS化したいとは思っているんです…


2015-03-19 FreeBSD 10.1-STABLE を更新したら時計の進み方が遅くなった?

FreeBSD 10.1-STABLE を更新したら時計の進み方が遅くなった?

普段から FreeBSD 10.1-STABLE を追いかけて使っていて、昨日 r279671 から r280208 へと更新したら時計の進み方がなんかおかしくなったことに気づく。気づいたのは、mikutter を起動しようとしたときのエラー。出ているメッセージからして、時刻がおかしいと言われているようなので、時計を見てみると数時間遅れている。

もともと ntpd は動かしていたが NTP で修正しきれる差分を超えていたので /etc/rc.conf に

ntpd_sync_on_start="YES"

と追加して再起動。再起動直後は正しい時刻を示しているのに、5分もするともう遅れていることに気づく。その後詳しく調べてみると、30秒でほぼ正確に10秒遅れる、つまり現実世界で30秒経過しても FreeBSD 上では20秒しか経っていない ⇔ 時間の進み方が 2/3 になってしまっていることがわかった。

この時点で、カーネルを更新した時にタイマ周りがおかしくなったことを疑う。更新前後のカーネルのリビジョンはわかっているのでカーネルのソースコードの差分を追おうと思えば追えるがめんどくさいのでやらない。

sysctl でタイムカウンターを確認してみると TSC-low (Time Stamp Counter) となっている。カーネル更新前はどうだったのかは今となってはわからない(/boot/kernel.old/kernel で起動すればわかるのだけど面倒なのでやらない)。

タイムカウンターが TSC になっているのでついでに machdep.tsc_freqも確認すると、3980954810 という数字になっている。カーネル更新前はどうだったのかは今となってはわからない(/boot/kernel.old/kernel で起動すればわかるのだけど面倒なのでやらない)。

$ sysctl kern.timecounter.hardware
kern.timecounter.hardware: TSC-low
$ sysctl machdep.tsc_freq
machdep.tsc_freq: 3980954810

このマシンの CPU クロック周波数は 2.66GHz(=2660000000Hz) なので 2660000000/3980954810 を計算してみると… ≒ 0.668 これだ!!!時間の進み方が 2/3 になっていたのとほぼ一致する。

試しに

# sysctl machdep.tsc_freq=2660000000

してみると、時間の進み方がほぼ正確になった。1桁少ない 266000000 にすると、時間の進み方が10倍になった。あとはこれを /etc/sysctl.conf に書き込んで恒久的に設定するだけなのだけど、今までは手で設定してなくてもうまく行っていたので、そもそもこうするべきなのかわからない。

よって、タイムカウンターを他のものに変更してみることにした。使用可能なタイムカウンターは kern.timecounter.choice で調べることができる。

$ sysctl kern.timecounter.choice
kern.timecounter.choice: TSC-low(1000) ACPI-safe(850) i8254(0) dummy(-1000000)

とりあえず ACPI-safe にしてみると、時間の進み方がほぼ正確になった。

# sysctl kern.timecounter.hardware=ACPI-safe

これでいいかということで /etc/sysctl.conf に

kern.timecounter.hardware="ACPI-safe"

と書き込んで再起動、しばらく動かしてみて時刻のズレが ntpd で補正できる範囲内に収まってることを確認。

参考にしたページ