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는 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 코드는 특정 타이머에 대한 지원이 부족하며 그 중 하나를 사용하면 syscall로 대체될 것이라고 말합니다. 해당 기사는 2017년 기사이며 자세한 내용은https://lore.kernel.org/linux-arm-kernel/[이메일 보호됨]/(2019년 6월)에서는 거의 모든(모두는 아니더라도) 타이머가 현재 vDSO를 지원한다고 제안하지만, 어쨌든 testgtod위에서 언급한 프로그램 은 CLOCK_REALTIME2017년 기사에 따르면 그 당시에는 vDSO를 지원했다고 나와 있습니다.

그래서 : 공식적으로 혼란 스럽습니다 :)

를 통해 읽기http://btorpey.github.io/blog/2014/02/18/clock-sources-in-linux/, 나는많은TSC에 대한 참조. 기사에서는 실제로 언급하지 않지만 RDTSC{,P}HPET에서 읽으려면 커널 수준 액세스(하드웨어 또는 타이머 값에 대한)가 필요하지만 사용자 공간에서 호출할 수 있는 권한 없는 명령일 수도 있다고 생각하기 시작했습니다 . syscall 폴백을 완전히 설명합니다.

참고로 내 T400의 Core2 P8600은 및 tsc을 지원 constant_tsc하지만 은 지원하지 않습니다 nonstop_tsc.

해당 사항 없음 더 많은 평판을 가진 사람이 하나 이상을 추가하려는 경우 존재합니다.

답변1

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

이것이 이유 다.

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_TSCsyscall을 사용하지 않고 시간을 읽습니다 RDTSC. VCLOCK_PVCLOCK또는 인 경우 VCLOCK_HVCLOCK특정 페이지에서 읽어 하이퍼바이저에서 정보를 검색합니다. HPET시계 모드를 선언하지 않습니다이므로 기본값으로 끝납니다.VCLOCK_NONE, 그리고 vDSO는 시간을 검색하기 위해 시스템 호출을 발행합니다.

연결한 패치 세트시계 전체에서 시계 처리를 통합하는 것이 아니라 아키텍처 전체에서 이를 통합하는 것입니다. vDSO를 지원하지 않는 클럭, HPET 및 ACPI가 여전히 몇 개 있습니다.

관련 정보