新しいシステムで17.10の適度に新しいインストールを実行し(完全にパッチ適用され、仮想化されていない)、/proc/stat
のbtime
エントリにリストされているブート時間が変化し続けることに気付きました。これにより、特定のプロセスが開始された実時間を計算するためにこの情報を使用するスクリプトが破損しました。
デバッグを行った結果、btime
はnow() - uptime
として計算され、btime
ドリフトは、システムクロックがアップタイムクロックとは異なるレートでインクリメントしていたためです。
これは、systemd-timesyncd.service
(つまり、ntpd
の置き換え)によってシステムクロックに適用された何らかのクロックスルーによるものと想定したため、テストとしてtimesyncd
を無効にして再起動しました。案の定、今ではアップタイムカウンターとシステムクロックは同じレートでステップします。 (また、 adjtimex
をインストールして、カーネルパラメーターをチェックし、クロックスルーが残っていないことを確認します。frequency
バイアスが適用されておらず、tick
値は10000である必要があります。)
ただし、timesyncd
をオンにしないと、システムクロックが非常に乱れていることが明らかです。クロックは135分間で約5分間失われました(〜-37000 ppm)。これは、システムクロックのドリフトを手動で推定するために約20分間でadjtimex -l -w
を使用して得たものに似ています(〜 -40000 ppm)。 (実際、ストップウォッチを使用して確認するだけで、/proc/uptime
も間違ったレートで増加していることがわかりました;〜-41000 ppm。それは一貫しています。)
CMOSクロックも少しオフです(135分間で30秒増加しました)が、これはシステムクロックに影響を与えないことです。起動時に。ブート時にシステムクロックレートを変更する/etc/adjtime
ファイルはありません。とにかく、上記のadjtimex
は、クロックティックフュージョンがなかったことを報告します。そのため、CMOSクロックがシステムクロックで発生する問題をどのように引き起こしているのか想像できません。
それでも、 一部のレポート がシステムクロックの問題を奇跡的に修正できることを示唆しているように、CMOSバッテリーを変更します。 (これが発生する可能性のある明白なメカニズムはありませんが。)
しかし、システムクロックが非常に間違っている理由について、他に説明はありますか?また、システムタイマーが非常に大量にオフになっているという事実に対する解決策はありますか?明らかにtimesyncd
を実行するだけでは問題は解決しません。これは、生成される過剰なクロックスルーに問題があるためです(上記を参照)。
adjtimex
を使用してカーネルパラメーターを直接変更できます(少なくともアップタイムとシステムクロックカウンターの同期を維持する必要があります)が、実際には+-500 ppmの範囲のクロックエラーに対処するためのものです。私が見ているのは3桁大きいです、そしてそれはいくつかのより重要な問題を示しているのだろうかと思います。
記録として、非常によく似たマシンに17.10をインストールしても、この問題は発生しません。
更新:CMOSバッテリーの変更は何もしなかった(疑わしい)。問題の最終的な解決については、以下を参照してください。
TSCクロックソースに問題があることがわかりました。短期的には、クロックソースを 'hpet'に変更する(一時的にecho hpet > /sys/devices/system/clocksource/clocksource0/current_clocksource
で、またはclocksource=hpet
を/etc/default/grub
のカーネルブートパラメーターに追加することで永続的に)この問題を回避できます。
さらに広く言えば、この問題は、Skylake XデスクトップCPUに関するLinuxカーネルのTSC処理のバグによるものです。これは 今後のカーネルリリース で修正する必要があります。
Update:上記のパッチからの1行の修正で現在のカーネルを再構築すると、実際には正しいTSCの動作が復元されます。