¿Debería ver llamadas al sistema clock_gettime() (no VDSO) en x86_64 usando HPET?

¿Debería ver llamadas al sistema clock_gettime() (no VDSO) en x86_64 usando HPET?

Mientras buscaba cómo usarlo gettimeofday()por enésima vez, decidí esta vez hacer una inmersión rápida en vDSO, ya que solo tenía una vaga conciencia de ello y me preguntaba si había algún problema de uso al que debería prestar atención.

De acuerdo ahttps://stackoverflow.com/questions/42622427/gettimeofday-not-using-vdso, si el vDSO está en uso, stracedeberíanuncamostrar gettimeofdayo clock_gettime.

Bueno, parece que mi ThinkPad T400 lleva algún tiempo averiado: siempre lo he visto*montones*de estas llamadas stracedesde que tengo uso de razón. (Particularmente de QEMU.)

Si intento testgtod.c(que se ejecuta gettimeofday()1000 veces) la pregunta anterior:

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

Actualmente, la única diferencia que puedo encontrar entre mi ThinkPad y mi computadora de escritorio i3 es que el i3 usa TSC, mientras que el ThinkPad usa HPET porque tsc: Marking TSC unstable due to TSC halts in idle. (Me pregunté si esto podría ser una cuestión de suspensión/reanudación, pero luego noté la marca de tiempo: esto es 1,53 segundos después del inicio). El T400 está (actualmente...) ejecutando Arch, mientras que el i3 ejecuta Debian 9.

La pregunta anterior también hacía referencia a dump-vdso.c. El vDSO del T400 me parece bastante bueno:

$ 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

Otro enlace que encontré,https://bert-hubert.blogspot.com/2017/03/on-linux-vdso-and-clockgettime.html, dice que el código vDSO carece de soporte para ciertos temporizadores y recurrirá a una llamada al sistema si usa uno de esos. Ese artículo es de 2017 y los detalles enhttps://lore.kernel.org/linux-arm-kernel/[correo electrónico protegido]/(junio de 2019) sugiere que casi todos (¿si no todos?) los temporizadores tienen soporte vDSO ahora, pero en cualquier caso, el testgtodprograma mencionado anteriormente se llama CLOCK_REALTIME, que según el artículo de 2017 era compatible con vDSO en ese entonces.

Entonces: estoy oficialmente confundido :)

leyendohttp://btorpey.github.io/blog/2014/02/18/clock-sources-in-linux/, Veo unlotede referencias al TSC. El artículo realmente no lo menciona, pero estoy empezando a pensar que tal vez RDTSC{,P}sea una instrucción sin privilegios que se puede llamar desde el espacio de usuario, mientras que la lectura desde HPET requiere acceso a nivel de kernel (a valores de hardware o temporizador). Lo que explicaría totalmente el retroceso de la llamada al sistema.

Por cierto, el Core2 P8600 de mi T400 admite tscy constant_tsc, pero no nonstop_tsc.

Ninguno de existieron, si alguien con más reputación quiere agregar uno o más de ellos.

Respuesta1

El artículo realmente no lo menciona, pero estoy empezando a pensar que tal vez RDTSC{,P}sea una instrucción sin privilegios que se puede llamar desde el espacio de usuario, mientras que la lectura desde HPET requiere acceso a nivel de kernel (a valores de hardware o temporizador). Lo que explicaría totalmente el retroceso de la llamada al sistema.

Esta es la razón.

Puede verificar el cambio en el comportamiento de vDSO entre los dos relojes en cualquier sistema que admita ambos tscy hpetcomo fuente de tiempo:

$ 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 +++

(Recuerde restaurar la fuente del reloj original).

RDTSCes una instrucción sin privilegios, y puedes ver un ejemplo de su uso enel manual del CCG: busque rdtscallí, compile el código de ejemplo y verá que puede ejecutarlo en el espacio de usuario. (Estrictamente hablando, RDTSCyRDTSCP puede ser privilegiado, no están por defecto en Linux, pero puedentener privilegios de usoprctl.)

En vDSO, clock_gettimeofdaylas funciones relacionadas dependen de modos de reloj específicos; ver__arch_get_hw_counter. Si el modo de reloj es VCLOCK_TSC, la hora se lee sin una llamada al sistema, usando RDTSC; si es VCLOCK_PVCLOCKo VCLOCK_HVCLOCK, se lee desde una página específica para recuperar la información del hipervisor. HPETno declara un modo de reloj, por lo que termina con el valor predeterminadoVCLOCK_NONEy el vDSO emite una llamada al sistema para recuperar la hora.

El conjunto de parches al que se vinculóNo se trataba de unificar el manejo del reloj entre relojes, sino de unificarlo entre arquitecturas. Todavía hay algunos relojes sin soporte vDSO, entre ellos HPET y ACPI.

información relacionada