Linux – Why Utilities Don’t Use System Call for Current Time

clocklinuxsyscalls

I'm really trying to understand why our guest VMs aren't using the kvm-clock driver "like they're supposed to". They're running RHEL 7.2, glibc-2.17, kern 3.10.0. Programs such as date and perl -e 'print time' get the current time, but do so without making a system call. This is confirmed with strace and ltrace and further confirmed by using gdb and tracing through assembly which bypassed the syscall and instead executed some instruction called rtdscp.

Is this an attempt at optimization by the glibc authors? Is there any way to disable this and force glibc calls to make the systemcall (short of LD_PRELOAD hacks)?

UPDATE 2016-10-14:

After reviewing the latest POSIX draft, part of the answer is clear: there is a way to request the clock from the CPU, but GNU glibc has wrongly forced this implementation on its users. The work-around is to invoke the system call directly. (Booooh)

If _POSIX_CPUTIME is defined, implementations shall support clock ID values obtained by invoking clock_getcpuclockid(), which represent the CPU-time clock of a given process. Implementations shall also support the special clockid_t value CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the calling process when invoking one of the clock_() or timer_() functions.

Given that the user can Is there any real argument against the notion that if clock_id is set to CLOCK_REALTIME, the system call should be used?

Best Answer

I think the reason you don't see a syscall happening, is that some Linux system calls (esp. those related to time, like gettimeofday(2) and time(2)) have special implementations through the vDSO, which contains somewhat optimized implementations of some syscalls:

The "vDSO" (virtual dynamic shared object) is a small shared library that the kernel automatically maps into the address space of all user-space applications.

There are some system calls the kernel provides that user-space code ends up using frequently, to the point that such calls can dominate overall performance. This is due both to the frequency of the call as well as the context-switch overhead that results from exiting user space and entering the kernel.

Now, the manual mentions that the required information is just placed in memory so that a process can access it directly (the current time isn't much of a secret, after all). I don't know about the exact implementation, and could only guess about the role of the CPU's time stamp counter in the it.

So, it's not really glibc doing an optimization, but the kernel. It can be disabled by setting vdso=0 on the kernel command line, and it should be possible to compile it out. I can't find if it's possible to disable it on the glibc side, however (at least without patching the library).

There's a bunch of other information and sources on this question on SE.


You said in the question:

After reviewing the latest POSIX draft, part of the answer is clear: there is a way to request the clock from the CPU, but GNU glibc has wrongly forced this implementation on its users.

Which I think is a rather bold statement. I don't see any evidence of "wrongly forcing" anything on users, at least not to their disadvantage. The vDSO implementation is used by almost every Linux process running on current systems, meaning that if it didn't work correctly, some very loud complaints would have been already heard. Also you said yourself that the time received is correct.

The quote you give from the clock_gettime manual only seems to mention that the call must support clock id's returned by clock_getcpuclockid, not anything about the behaviour of CLOCK_REALTIME or gettimeofday.

Related Question