[PATCH] Linux: Use 32-bit vDSO for clock_gettime, gettimeofday, time (bug 28071)

Florian Weimer fweimer@redhat.com
Mon Jul 12 14:29:20 GMT 2021


* Adhemerval Zanella:

>> I'm a bit surprised that we still see the extra syscalls with your
>> patch, but I suppose that's just the way the INTERNAL_VSYSCALL_CALL
>> macro works.
>
> The INTERNAL_VSYSCALL_CALL issues the syscall if the vDSO is not present
> as a fallback mechanism.  It should not be really necessary on most 
> implementation currently, but there are some architectures and kernel
> version where the vDSO does not actually does it (I think mips on kernel
> 4.x version).

But we check the function pointer before that, so we should never hit
the fallback path.  That's what confuses me.

Here's what I see on s390-linux-gnu (7.9.z).  System glibc
(glibc-2.17-324.el7_9.s390):

munmap(0x7d4e3000, 35579)               = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7d4eb000
write(1, "errno = Success (0)\n", 20errno = Success (0)
)   = 20
write(1, "errno = Success (0)\n", 20errno = Success (0)
)   = 20
exit_group(1)                           = ?

Current development glibc with your patch applied on top:

ugetrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
syscall_0x193(0, 0x7f916310, 0x7f91652c, 0x7f9163fc, 0x400638, 0x7f916518) = -1 ENOSYS (Function not implemented)
clock_gettime(CLOCK_REALTIME, {tv_sec=1626099916, tv_nsec=791410856}) = 0
statx(1, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_BASIC_STATS, 0x7f915a90) = -1 ENOSYS (Function not implemented)
fstatat64(1, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}, AT_EMPTY_PATH) = 0
getrandom("\x16\x60\xeb\x47", 4, GRND_NONBLOCK) = 4
brk(NULL)                               = 0x7d9e9000
brk(0x7da0a000)                         = 0x7da0a000
write(1, "errno = Success (0)\n", 20errno = Success (0)
)   = 20
syscall_0x193(0x1, 0x7f916310, 0x14, 0xfd46054a, 0x400638, 0x7f916518) = -1 ENOSYS (Function not implemented)
clock_gettime(CLOCK_MONOTONIC, {tv_sec=29888, tv_nsec=604781810}) = 0
write(1, "errno = Success (0)\n", 20errno = Success (0)
)   = 20

The vdso has this (according to
/lib/modules/3.10.0-1160.31.1.el7.s390x/vdso/vdso32.so, have not checked
at run time):

    2: 00000300     84 FUNC    GLOBAL DEFAULT        7 __kernel_clock_getres@@LINUX_2.6.29
    3: 00000230    208 FUNC    GLOBAL DEFAULT        7 __kernel_gettimeofday@@LINUX_2.6.29
    5: 00000354    410 FUNC    GLOBAL DEFAULT        7 __kernel_clock_gettime@@LINUX_2.6.29

>> Regarding the actual patch, there are a few missing spaces before
>> parenthesis:
>> 
>> +  int (*vdso_time64)(clockid_t clock_id, struct __timespec64 *tp)
>> +    = GLRO(dl_vdso_clock_gettime64);
>> +  int (*vdso_time)(clockid_t clock_id, struct timespec *tp)
>> +    = GLRO(dl_vdso_clock_gettime);
>
> My understanding is for GLRO the space is not really required because the
> macro is not used a function call.  I followed the same idea for the
> function pointer definition.

I think the the ( in the pointer type still qualifies for the space
because it is related to function application.  We use the space in all
prototypes, after all.

> Regardless of the missing space, are you ok with my patch then? 

It gets rid of the ENOSYS error, so it is a step forward.

Thanks,
Florian



More information about the Libc-alpha mailing list