HPETを使用してx86_64で(VDSOではなく)clock_gettime()システムコールを表示する必要がありますか?

HPETを使用してx86_64で(VDSOではなく)clock_gettime()システムコールを表示する必要がありますか?

どのように使用するのか何度も調べた後、gettimeofday()vDSOについて漠然と知っていたし、注意すべき使用上問題があるのか​​知りたかったので、今回vDSOについて素早く調べることにしました。 。

~によるとhttps://stackoverflow.com/questions/42622427/gettimeofday-not-using-vdso, vDSO を使用するstrace場合いいえ表示gettimeofdayまたはclock_gettime

まあ、私のThinkPad T400がしばらく故障しているようです。*トン*strace私が覚えている限り、私はこのような電話を受けたことがあります。 (特にQEMUで)

上記の質問を試してみるとtestgtod.c(1000回実行):gettimeofday()

$ strace ./testgtod 2>&1 | grep clock_gettime | wc -l
1000

現在、ThinkPadとi3デスクトップの間にある唯一の違いは、i3がTSCを使用しているのに対し、ThinkPadはHPETを使用していることですtsc: Marking TSC unstable due to TSC halts in idle。 (これが一時停止/再開の問題かどうか疑問に思いましたが、タイムスタンプを確認しました。これは起動後1.53秒です。)T400(現在...)はArchを実行しており、i3ボックスはDebian 9を実行しています。

上記の質問も参照されますdump-vdso.c。 T400のvDSOは私の目にはかなりよさそうです。

$ objdump -T vdso.so

vdso.so:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
0000000000000740  w   DF .text  000000000000005e  LINUX_2.6   clock_gettime
00000000000007a0 g    DF .text  0000000000000067  LINUX_2.6   __vdso_gettimeofday
00000000000007a0  w   DF .text  0000000000000067  LINUX_2.6   gettimeofday
0000000000000810 g    DF .text  0000000000000010  LINUX_2.6   __vdso_time
0000000000000810  w   DF .text  0000000000000010  LINUX_2.6   time
0000000000000740 g    DF .text  000000000000005e  LINUX_2.6   __vdso_clock_gettime
0000000000000000 g    DO *ABS*  0000000000000000  LINUX_2.6   LINUX_2.6
0000000000000820 g    DF .text  0000000000000025  LINUX_2.6   __vdso_getcpu
0000000000000820  w   DF .text  0000000000000025  LINUX_2.6   getcpu

私が見つけた別のリンクは、https://bert-hubert.blogspot.com/2017/03/on-linux-vdso-and-clockgettime.htmlは、vDSOコードが特定のタイマーのサポートを欠いていて、タイマーの1つを使用している場合はシステムコールに置き換えられることを示します。この記事は2017年の記事です。詳細については、次を参照してください。https://lore.kernel.org/linux-arm-kernel/[Eメール保護]/(2019年6月)では、ほとんどすべて(すべてではなく)タイマーが現在vDSOをサポートしていることを示唆していますが、それにもかかわらず上記のtestgtodプログラムはvDSOと呼ばれ、CLOCK_REALTIME2017年の記事ではそのプログラムが当時vDSOをサポートしていると述べました。

だから:混乱しています:)

最後まで読んでhttp://btorpey.github.io/blog/2014/02/18/clock-sources-in-linux/、私は〜を見たたくさんTSCを参照してください。記事では実際に言及していませんが、RDTSC{,P}HPETで読み取るには、カーネルレベルのアクセス(ハードウェアまたはタイマー値に対する)が必要ですが、ユーザー空間で呼び出すことができる権限のないコマンドである可能性があると考え始めました。これはシステムコールフォールバックを完全に説明します。

ちなみに、私のT400のCore2 P8600はとをtscサポートしていconstant_tscますが、サポートしていませんnonstop_tsc

いいえ より評判の高い人がそのうちの1つ以上を追加したい場合は存在します。

答え1

RDTSC{,P}記事では実際に言及していませんが、HPETで読み取るには、カーネルレベルのアクセス(ハードウェアまたはタイマー値に対する)が必要ですが、ユーザー空間で呼び出すことができる権限のないコマンドである可能性があると考え始めました。これはシステムコールフォールバックを完全に説明します。

だから。

tschpetタイムソースをサポートし、機能するすべてのシステムで、2つのクロック間のvDSOの動作の変化を確認できます。

$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
tsc hpet acpi_pm

$ echo tsc | sudo tee /sys/devices/system/clocksource/clocksource0/current_clocksource > /dev/null

$ strace -e clock_gettime date
Sun 24 Nov 10:49:49 CET 2019
+++ exited with 0 +++

$ echo hpet | sudo tee /sys/devices/system/clocksource/clocksource0/current_clocksource > /dev/null

$ strace -e clock_gettime date
clock_gettime(CLOCK_REALTIME, {tv_sec=1574589034, tv_nsec=589851883}) = 0
Sun 24 Nov 10:50:34 CET 2019
+++ exited with 0 +++

(元のクロックソースを復元することを忘れないでください。)

RDTSC権限のないコマンドなので、次の使用例を見ることができます。GCCハンドブックrdtscそこから検索してサンプルコードをコンパイルすると、ユーザースペースで実行できることがわかります。RDTSC(厳密に言えば、RDTSCP 特権を享受できる、Linuxではデフォルトでは提供されていませんが、次のことができます。特権的使用を得るprctl.)

vDSOでは、clock_gettimeofday関連する機能は特定のクロックモードによって異なります。__arch_get_hw_counter。ウォッチフェイスがある場合はVCLOCK_TSCシステムコールなしで時間を読み取ることができます。または、特定RDTSCのページを読み取ってハイパーバイザーから情報を取得します。高温PETVCLOCK_PVCLOCKVCLOCK_HVCLOCK時計モードが宣言されていません。したがって、デフォルト値になります。VCLOCK_NONE、そしてvDSOは時間を取得するためにシステムコールを発行します。

接続したパッチセットこれは、複数のクロックにわたってクロック処理を統合するのではなく、アーキテクチャ全体でクロック処理を統合することです。 HPETやACPIを含むvDSOをサポートしていないクロックもあります。

関連情報