Debian 9(拡張)のクロック不安定性

Debian 9(拡張)のクロック不安定性

カーネル3.2-rtにダウングレードされたDebian 8(jessie)を実行しているコンピュータがあります。これはリアルタイム優先順位(SCHED_RR)に設定されたアプリケーションを実行し、1msごとに起きていくつかの処理を実行し、100msごとに別のPCにシリアルメッセージを送信することです。これは非常にうまく機能します。 (マシンは実際には基本サービス以外のものを実行しません。特にデスクトップではありません。)

カーネル4.9-rtを使用してDebian 9(stretch)にアップグレードしようとしたときに、いくつかの問題に遭遇しました。最大の問題の1つは時計の安定性でした。最初は正常に動作しているように見えましたが、起動した直後に次のような結果が得られました。

clocksource: timekeeping watchdog on CPU0: Marking clocksource 'tsc' as unstable because the skew is too large:
clocksource:                       'acpi_pm' wd_now: 74c6dd wd_last: 8dd916 mask: ffffff
clocksource:                       'tsc' cs_now: 119ac91c7b1 cs_last: 1158a25441d mask: ffffffffffffffff
clocksource: Switched to clocksource acpi_pm

最初にこれが発生した場合、上記のメッセージは "hpet"への移行を報告します。この遷移が発生した後、システムのすべてのタイミングが不安定に見える。clock_gettime(CLOCK_MONOTONIC, ...)タイミングで使用されたコードは4msごとに報告されます。 1msが目を覚ますと、シリアルメッセージは実際には100ミリ秒ごとではなく200ミリ秒ごとに送信されますが、シリアルメッセージ内のタイムスタンプは66ミリ秒ごとに送信されると見なされます。 (これらのいくつかは、実際のミリ秒の代わりに目覚めティックを計算することができます。)

BIOSでHPETを無効にしようとしましたが、上記のエラーが発生し、上記の内容が記録されるまで起動時に再び正常に実行されました。この時点ではほとんどが正常に動作しているように見えましたが、時にはいくつかのタイマーが負の持続時間を報告しました。

もう1つの主な問題は、1ミリ秒ごとに実行される処理コードがJessieでは実行するのに約200usかかりますが、Stretchでは明らかな理由なしに実行されるのに900usがかかることです。実行しperf recordてみましたが、ほとんどの時間(サンプルの40%)がsys_clock_gettime

どちらの場合も、ハードウェアは同じです。AMD64ベースのi7-7700K CPUを搭載したSupermicro X11SSQマザーボードです。 CPU調整はBIOSで無効になっていますが、次constant_tscのように報告されますnonstop_tsc

if clock_gettime() < wakeup then sched_yield()アプリケーションが処理コードをスケジュールするために忙しい待機ループ(単純な擬似コード)を実行していることは興味深いかもしれません。

実験では、私はそれをsleep(clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &wakeup))に変更し、少なくともこれまでのクロックソースエラーは再び発生しませんでした(他のクロックとは異なり)、うまく動作しているように見えるtscクロックをまだ使用しています。

しかし、ウェイクアップジッタはもう10倍悪くなりました。睡眠中は700-1200us(SD 36us)、忙しい待機中は890-1120us(SD 2us)です。

追加の実験でこれをSCHED_DEADLINE(単一使用sched_yield())に変更してみましたが、これはclock_nanosleepと同じ動作をします。

JessieとStretchの間(または3.2と4.9の間で)この動作がなぜ変更されたのかご存知ですか?システムクロックを大幅に損なうことなく低ジッタ待機を達成するためのより良い方法はありますか?

答え1

GRUB_CMDLINE_LINUX_DEFAULT行に/etc/default/grub "notsc Clocksource = acpi_pm"を追加してください。

私の現在の状況は次のとおりです。

GRUB_CMDLINE_LINUX_DEFAULT="quiet notsc clocksource=acpi_pm"

次に、次のようにします。sudo update-grub

利用可能な他のクロックソースを設定できます。

cat /sys/devices/system/clocksource/clocksource0/available_clocksource

関連情報