This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC v1 01/16] sysdeps/nanosleep: Use clock_nanosleep_time64 instead of nanosleep


On Mon, Jun 24, 2019 at 4:52 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> 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

Ok, so it sounds like the correct solution is to do the above
#ifdef-ing for all the problematic syscalls. I'll do that and send an
v2.

Alistair

> --


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]