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 코드가 특정 타이머에 대한 지원이 부족하고 타이머 중 하나를 사용하는 경우 시스템 호출로 대체됨을 나타냅니다. 해당 기사는 2017년 기사입니다. 자세한 내용은 다음을 참조하세요.https://lore.kernel.org/linux-arm-kernel/[이메일 보호됨]/(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

RDTSC{,P}기사에서는 실제로 언급하지 않지만, HPET에서 읽으려면 커널 수준 액세스(하드웨어 또는 타이머 값에 대한)가 필요하지만 사용자 공간에서 호출할 수 있는 권한 없는 명령일 수 있다고 생각하기 시작했습니다 . 이것은 시스템 호출 폴백을 완전히 설명합니다.

그렇기 때문에.

tschpet시간 소스를 지원하고 역할을 하는 모든 시스템에서 두 시계 사이의 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를 지원하지 않는 시계도 있습니다.

관련 정보