Message ID | cf7ecd7aa844bf65b1f1426f8a2153c78ee72281.1561177967.git.alistair.francis@wdc.com |
---|---|
State | New, archived |
Headers |
Received: (qmail 88535 invoked by alias); 22 Jun 2019 04:39:57 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <libc-alpha.sourceware.org> List-Unsubscribe: <mailto:libc-alpha-unsubscribe-##L=##H@sourceware.org> List-Subscribe: <mailto:libc-alpha-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/libc-alpha/> List-Post: <mailto:libc-alpha@sourceware.org> List-Help: <mailto:libc-alpha-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 88490 invoked by uid 89); 22 Jun 2019 04:39:56 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3 autolearn=ham version=3.3.1 spammy=interrupted X-HELO: esa2.hgst.iphmx.com DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1561178450; x=1592714450; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3LaS0zHUBwxSIkPsg15cyI/pnVjvKLu2KWvRiHEZ9dM=; b=jBl0iP+UfHgce8JQIVZICqJNiCKszcbZQRUG828nx+xD+fSeTxfOVC3z qc5NqV9U3iPqGLnY62ox34x7Lk7wra8TtPnTQ3+MFGokMszJ8LtPABj2E cpR3gdyVVbtoBKfsql/SHaXCuSqGn+jtjBcg29I4ySf+zt10rrIx4/VOF ocDXqszXxeHZA7NIO3IP5SooniRH9oGsnQmfE84VY6w3eQn5ETffCmMKC bWD4nNHGc4v4TxajQZdR9XyhINd/67xTSdfYWc20dRlDM4c05DWDClNRh 9Jow0i3AJyAEaLrxJchWBNFN61EtLGq+8XZn6WLP+kJeIMO7SF5fMMu47 w==; IronPort-SDR: 1tS2bbF51aXJgVTjkbPpMArowVIGfVJhkttNGNd9YrfHePq/jdwloGhXIkwhiZM8Y1r17MTGdY iLp8HOg0/ct1Cxqb1wMvKu/WqbDOn/a+J3wWqLM03rcriazFpatdyDtekIngsRbKPNwSUE85UN VMznFVYeu6tJbVAgbF1Wm3rHN87VH+W69h7N0pZueTubzF9BSjJ2+eodtWTr24KaSb2nB9lw3n VLmz7g/RHyf7Gakjk3Yh03c/DjFHzLpmwDDTSMxHhCuoVmu0Q/XExb7IohNwKVxl7xhC+yjB66 A7VZ7QZtozhVZNfZUR+Q9fpj IronPort-SDR: OCkxCpkRg9iJ9D9ervZOX60Q/FGYZw7EDV4hBaDrLuyX8yfFPiEmRTZpzQNkhlid3kW84pvmUo E1HUoSCTO786QP0LC4H6zoj9kDMJddeXaDQlbFTFZ3MSefB8D3VAcUbK351iGHqxYELvFKH8fj 82g9FacX7M6jhBA2/m2q26xa/U2pI/C0fEkH1uZLZdU/+wtkkTu0b0fT/YnypEapjpshHuX+Dj aN70936GQPde5nikKwxYpxqL7Im/ulUf41BRg2C1fnHGvji4UQ9fOJeTbkm2aiT6uOiobdEC1v eCQ= From: Alistair Francis <alistair.francis@wdc.com> To: libc-alpha@sourceware.org Cc: alistair.francis@wdc.com, alistair23@gmail.com Subject: [RFC v1 01/16] sysdeps/nanosleep: Use clock_nanosleep_time64 instead of nanosleep Date: Fri, 21 Jun 2019 21:37:15 -0700 Message-Id: <cf7ecd7aa844bf65b1f1426f8a2153c78ee72281.1561177967.git.alistair.francis@wdc.com> In-Reply-To: <cover.1561177967.git.alistair.francis@wdc.com> References: <cover.1561177967.git.alistair.francis@wdc.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit |
Commit Message
Alistair Francis
June 22, 2019, 4:37 a.m. UTC
The nanosleep syscall is not supported on newer 32-bit platforms (such
as RV32). To fix this issue let's change to using clock_nanosleep_time64
instead.
Let's use CLOCK_REALTIME when calling clock_nanosleep_time64 as the
Linux specification says:
"POSIX.1 specifies that nanosleep() should measure time against the
CLOCK_REALTIME clock. However, Linux measures the time using the
CLOCK_MONOTONIC clock. This probably does not matter, since the POSIX.1
specification for clock_settime(2) says that discontinuous changes in
CLOCK_REALTIME should not affect nanosleep()"
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
ChangeLog | 6 ++++++
nptl/thrd_sleep.c | 3 ++-
sysdeps/unix/sysv/linux/nanosleep.c | 3 ++-
sysdeps/unix/sysv/linux/nanosleep_nocancel.c | 3 ++-
4 files changed, 12 insertions(+), 3 deletions(-)
Comments
* 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? Thanks, Florian
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? The main goal of this RFC series was to get feedback if this is in the right direction, or maybe I'm just missing something much simpler. Alistair > > Thanks, > Florian
* 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 This is somewhat hackish, but it's reasonably accurate for architectures that provide standard system calls under non-standard names for some reason. Obviously, this assume that for these new ports, the UAPI headers do the right thing and use 64-bit time_t for the old structs as well. Thanks, Florian
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 :) > > Obviously, this assume that for these new ports, the UAPI headers do the > right thing and use 64-bit time_t for the old structs as well. AFAIK they should be, at least in this case. Alistair > > Thanks, > Florian
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. 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. Arnd
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 Alistair > > Arnd
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 --
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 > --
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 Neither of these work as in this case __NR_syscall() isn't defiend. We can't include it at all for glibc to compile. Alistair > --
On Mon, Jun 24, 2019 at 4:05 PM Alistair Francis <alistair23@gmail.com> wrote: > > 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 > > Neither of these work as in this case __NR_syscall() isn't defiend. We > can't include it at all for glibc to compile. Nevermind, I think I figured it out. I'll send a v2. Alistair > > Alistair > > > --
diff --git a/ChangeLog b/ChangeLog index 05291d7825..b90c5ab60c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +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. + 2019-06-20 Dmitry V. Levin <ldv@altlinux.org> Florian Weimer <fweimer@redhat.com> diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c index 07a51808df..82a3b84366 100644 --- a/nptl/thrd_sleep.c +++ b/nptl/thrd_sleep.c @@ -25,7 +25,8 @@ int thrd_sleep (const struct timespec* time_point, struct timespec* remaining) { INTERNAL_SYSCALL_DECL (err); - int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, remaining); + int ret = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, + CLOCK_REALTIME, 0, time_point, remaining); if (INTERNAL_SYSCALL_ERROR_P (ret, err)) { /* C11 states thrd_sleep function returns -1 if it has been interrupted diff --git a/sysdeps/unix/sysv/linux/nanosleep.c b/sysdeps/unix/sysv/linux/nanosleep.c index f14ae565af..bb40121fb6 100644 --- a/sysdeps/unix/sysv/linux/nanosleep.c +++ b/sysdeps/unix/sysv/linux/nanosleep.c @@ -25,7 +25,8 @@ int __nanosleep (const struct timespec *requested_time, struct timespec *remaining) { - return SYSCALL_CANCEL (nanosleep, requested_time, remaining); + return SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, 0, + requested_time, remaining); } hidden_def (__nanosleep) weak_alias (__nanosleep, nanosleep) diff --git a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c index 122ba627ff..8cc56f42d0 100644 --- a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c +++ b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c @@ -24,6 +24,7 @@ int __nanosleep_nocancel (const struct timespec *requested_time, struct timespec *remaining) { - return INLINE_SYSCALL_CALL (nanosleep, requested_time, remaining); + return INLINE_SYSCALL_CALL (clock_nanosleep_time64, CLOCK_REALTIME, 0, + requested_time, remaining); } hidden_def (__nanosleep_nocancel)