This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [RFC v1 01/16] sysdeps/nanosleep: Use clock_nanosleep_time64 instead of nanosleep
On 23/06/2019 20:42, Alistair Francis wrote:
> On Sun, Jun 23, 2019 at 12:35 PM Arnd Bergmann <arnd@arndb.de> wrote:
>>
>> On Sun, Jun 23, 2019 at 7:00 PM Alistair Francis <alistair23@gmail.com> wrote:
>>> On Sun, Jun 23, 2019 at 9:48 AM Florian Weimer <fweimer@redhat.com> wrote:
>>>> * Alistair Francis:
>>>>> On Sat, Jun 22, 2019 at 11:34 PM Florian Weimer <fweimer@redhat.com> wrote:
>>>>>>
>>>>>> * Alistair Francis:
>>>>>>
>>>>>>> +2019-06-21 Alistair Francis <alistair.francis@wdc.com>
>>>>>>> +
>>>>>>> + * nptl/thrd_sleep.c: Use clock_nanosleep_time64 instead of nanosleep.
>>>>>>> + * sysdeps/unix/sysv/linux/nanosleep.c: Likewise.
>>>>>>> + * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise.
>>>>>>
>>>>>> Sorry, how is this supposed to work for all the other architectures
>>>>>> which don't have this system call with current kernel versions?
>>>>>
>>>>> Good question, I'm sure it doesn't.
>>>>>
>>>>> If we put this around #if defined(clock_nanosleep_time64) or #ifndef
>>>>> clock_nanosleep and then keep the current code as the #else would that
>>>>> be acceptable to upstream?
>>>>
>>>> Does this work in <sysdep.h> for the port?
>>>>
>>>> #define __NR_clock_nanosleep __NR_clock_nanosleep_time64
>>>
>>> I'm at home today so I can't check, but I suspect that will work.
>>>
>>>>
>>>> This is somewhat hackish, but it's reasonably accurate for architectures
>>>> that provide standard system calls under non-standard names for some
>>>> reason.
>>>
>>> For the RV32 case I think this will provide a workable solution. I am
>>> under the impression though that all 32-bit architectures are
>>> eventually removing __ARCH_WANT_TIME32_SYSCALLS from Linux so they
>>> will also hit this issue. Which is why I was going for a more generic
>>> approach. In saying that, whatever gets the RV32 port in works for me
>>> :)
>>
>> Generally speaking we never remove system calls from the kernel, rv32
>> was the exception to this rule because there was no upstream C library
>> port. __ARCH_WANT_TIME32_SYSCALLS will probably hang around for
>> shortly before year 2038 -- afterwards there is no point any more as all
>> binaries relying on it will be broken then.
>>
>> We will however allow building kernels that omit the time32 syscalls
>> before then, as they are only adding baggage to the kernel size and
>> make it harder to verify that user space doesn't try calling them.
>>
>> I think for internal libc functions, you need to try both functions:
>> first the time64 version for kernels that leave out the 32-bit one,
>> and then the time32 version for running on pre-5.1 kernels.
>
> Ok, so if I re-jig the series to #ifdef the 64-bit syscall first and
> then fall back to the standard (32-bit) syscall that will be the
> correct solution?
>
>
>>
>> For user-visible glibc interfaces (e.g. nanosleep()), user space with
>> a 64-bit time_t will have to try the time64 syscall first and then fall
>> back on the time32 version for pre-5.1 kernels, while user space
>> with 32-bit time_t should only call the old time32 syscall and fail
>> on any kernel that doesn't support that, either because
>> __ARCH_WANT_TIME32_SYSCALLS is not set at compile
>> time, or because the kernel was configured without these.
>
> Ok, so this seems to just be changing the #ifdef logic to something like this:
>
> #ifdef time_t == 64
> # ifdef __NR_syscall64
> __NR_syscall64()
> # else
> __NR_syscall()
> # endif
> #else /* time_t == 64*/
> __NR_syscall()
> #endif
>
> Although that just simplifies to:
>
> # ifdef __NR_syscall64
> __NR_syscall64()
> # else
> __NR_syscall()
> # endif
>
Kernel seems to allow builds with disabled time32 syscalls and if it were indeed
used on deployments we will need to do change the glibc implementation to do:
--
#ifdef __NR_syscall64
long int ret = __NR_syscall64 ();
if (ret == 0 || errno != ENOSYS)
return ret;
#endif
return __NR_syscall ();
--
We can optimize by adding __ASSUME macros on kernel-features to explicit make
syscall64 is always used, which will turn to previous logic to:
--
#ifdef __ASSUME_syscall64
return __NR_syscall64 ();
#else
# ifdef __NR_syscall64
long int ret = __NR_syscall64 ();
if (ret == 0 || errno != ENOSYS)
return ret;
# endif
return __NR_syscall ();
#endif
--