clock_gettiimer: syscall vs vdso

Adhemerval Zanella adhemerval.zanella@linaro.org
Wed Mar 11 13:12:27 GMT 2020



On 10/03/2020 21:09, Hal Murray wrote:
> 
> What determines if clock_gettiimer uses vdso or does a syscall?
> 
> I'm using seccomp.  I have code that has been running fine without allowing 
> clock_gettiimer.  Suddenly, I'm getting traps when clock_gettiimer does a 
> syscall.  If I run my timing hack, sure enough, clock_gettiimer is much slower 
> than I remember.
> 
> This is happening on Fedora 31, x86_64
> I haven't noticed troubles on other distros or architectures but haven't gone 
> looking.
> 
> I can't think of anything I've done that would trigger this.
> 
> Is there anything user code can do that would influence this?
> 
> Any hints on tracking this down?

It depends of the underlying kernel and architecture.  For ABI with
64 bit time_t, glibc will first check if vDSO pointer is correctly
initialized (if the architecture defines to actually setup a vDSO
pointer) and use it, or issue the syscall directly.  Keep in mind 
that kernel usually only support userland support for CLOCK_REALTIME
or CLOCK_MONOTONIC, for other clocks vDSO symbol will issue a syscall
(some mips kernels do not fallback to a syscall in such cases, but
it should be handled by glibc).

One change also done on glibc 2.31 (commit 1bdda52fe9) was to move
the vDSO pointer setup to ld.so. It allowed to remove the pointer
mangling/demangling, make the syscall available for preload libraries
(malloc replacement, for instance), and slightly increase security
because the vDSO pointers are marked as read-only after symbol
resolution.

Now for architecture where kernel added 64-bit time_t support on
recent version (linux 5.1), glibc 2.31 will try to first issue the
64-bit time_t syscall and then fallback to vDSO/time_t 
(commit ec138c67cb). The 64-bit time_t vDSO support was also added
one some architecture (commit ff500a623d1b), to say i386
(commit 2d77a447510c18e, kernel support added on Linux 5.3),
arm (commit 93e4db49b424fef, kernel supported added on Linux 5.5),
and mips (cdae973b6a7eb, kernel support added on Linux 5.4). In this
case, the 64-bit vDSO will be used, then 64-bit syscall, and if both
fails then 32-bit vDSO, and finally 32-bit syscall.

Also on glibc 2.31 (commit a9091a12444d55) it was added a optimization
on 32-bit clock_gettime fallback: if underlying kernel does not support
64-bit clock_gettime (kernel returns ENOSYS), the fallback won't try 
to issue the 64-bit syscall again and it will use the 32-bit vDSO/syscall
directly.
 



More information about the Libc-help mailing list