On 26/07/22 10:30, Jason A. Donenfeld wrote: > + l = __getrandom_nocancel (p, n, 0); > + if (l > 0) > + { > + if ((size_t) l == n) > + return; /* Done reading, success. */ > + p = (uint8_t *) p + l; > + n -= l; > + continue; /* Interrupted by a signal; keep going. */ > + } > + else if (l == 0) > + arc4random_getrandom_failure (); /* Weird, should never happen. */ > + else if (l == -EINTR) > + continue; /* Interrupted by a signal; keep going. */ > + else if (!__ASSUME_GETRANDOM && l == -ENOSYS) > + { > + atomic_store_relaxed (&have_getrandom, false); I still think there is no much gain in this optimization, the syscall will most likely be present and it is one less static data. Also, we avoid to use __ASSUME_GETRANDOM on generic code (all __ASSUME usage within sysdeps and/or nptl). > diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile > index 2ccc92b6b8..2f4f9784ee 100644 > --- a/sysdeps/unix/sysv/linux/Makefile > +++ b/sysdeps/unix/sysv/linux/Makefile > @@ -380,7 +380,8 @@ sysdep_routines += xstatconv internal_statvfs \ > open_nocancel open64_nocancel \ > openat_nocancel openat64_nocancel \ > read_nocancel pread64_nocancel \ > - write_nocancel statx_cp stat_t64_cp > + write_nocancel statx_cp stat_t64_cp \ > + ppoll_nocancel > > sysdep_headers += bits/fcntl-linux.h > > diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions > index 65d2ceda2c..febe1ad421 100644 > --- a/sysdeps/unix/sysv/linux/Versions > +++ b/sysdeps/unix/sysv/linux/Versions > @@ -320,6 +320,7 @@ libc { > __read_nocancel; > __pread64_nocancel; > __close_nocancel; > + __ppoll_infinity_nocancel; > __sigtimedwait; > # functions used by nscd > __netlink_assert_response; There is no need to export on GLIBC_PRIVATE, since it is not currently usage libc.so. Just define is a hidden (attribute_hidden). > diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h > index 74adc3956b..75d5f953d4 100644 > --- a/sysdeps/unix/sysv/linux/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/kernel-features.h > @@ -236,4 +236,11 @@ > # define __ASSUME_FUTEX_LOCK_PI2 0 > #endif > > +/* The getrandom() syscall was added in 3.17. */ > +#if __LINUX_KERNEL_VERSION >= 0x031100 > +# define __ASSUME_GETRANDOM 1 > +#else > +# define __ASSUME_GETRANDOM 0 > +#endif > + > #endif /* kernel-features.h */ > diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h > index 2c58d5ae2f..d3df8fa79e 100644 > --- a/sysdeps/unix/sysv/linux/not-cancel.h > +++ b/sysdeps/unix/sysv/linux/not-cancel.h > @@ -23,6 +23,7 @@ > #include <sysdep.h> > #include <errno.h> > #include <unistd.h> > +#include <sys/poll.h> > #include <sys/syscall.h> > #include <sys/wait.h> > #include <time.h> > @@ -77,6 +78,10 @@ __getrandom_nocancel (void *buf, size_t buflen, unsigned int flags) > /* Uncancelable fcntl. */ > __typeof (__fcntl) __fcntl64_nocancel; > > +/* Uncancelable ppoll. */ > +int > +__ppoll_infinity_nocancel (struct pollfd *fds, nfds_t nfds); Use attribute_hidden here and remove it from sysdeps/unix/sysv/linux/Versions. > + > #if IS_IN (libc) || IS_IN (rtld) > hidden_proto (__open_nocancel) > hidden_proto (__open64_nocancel) > @@ -87,6 +92,7 @@ hidden_proto (__pread64_nocancel) > hidden_proto (__write_nocancel) > hidden_proto (__close_nocancel) > hidden_proto (__fcntl64_nocancel) > +hidden_proto (__ppoll_infinity_nocancel) > #endif > > #endif /* NOT_CANCEL_H */ Also update the hurd sysdeps/mach/hurd/not-cancel.h with a wrapper to __poll (since it does not really support pthread cancellation). > diff --git a/sysdeps/generic/chacha20_arch.h b/sysdeps/unix/sysv/linux/ppoll_nocancel.c > similarity index 62% > rename from sysdeps/generic/chacha20_arch.h > rename to sysdeps/unix/sysv/linux/ppoll_nocancel.c > index 1b4559ccbc..28c8761566 100644 > --- a/sysdeps/generic/chacha20_arch.h > +++ b/sysdeps/unix/sysv/linux/ppoll_nocancel.c > @@ -1,5 +1,5 @@ > -/* Chacha20 implementation, generic interface for encrypt. > - Copyright (C) 2022 Free Software Foundation, Inc. > +/* Linux ppoll syscall implementation -- non-cancellable. > + Copyright (C) 2018-2022 Free Software Foundation, Inc. > This file is part of the GNU C Library. > > The GNU C Library is free software; you can redistribute it and/or > @@ -16,9 +16,16 @@ > License along with the GNU C Library; if not, see > <https://www.gnu.org/licenses/>. */ > > -static inline void > -chacha20_crypt (uint32_t *state, uint8_t *dst, const uint8_t *src, > - size_t bytes) > +#include <unistd.h> > +#include <sysdep-cancel.h> > +#include <not-cancel.h> > + > +int > +__ppoll_infinity_nocancel (struct pollfd *fds, nfds_t nfds) > { > - chacha20_crypt_generic (state, dst, src, bytes); > +#ifndef __NR_ppoll_time64 > +# define __NR_ppoll_time64 __NR_ppoll > +#endif > + return INLINE_SYSCALL_CALL (ppoll_time64, fds, nfds, NULL, NULL, 0); > } > +hidden_def (__ppoll_infinity_nocancel) Maybe just add an inline wrapper on sysdeps/unix/sysv/linux/not-cancel.h, as for __getrandom_nocancel: static inline int __ppoll_infinity_nocancel (struct pollfd *fds, nfds_t nfds) { #ifndef __NR_ppoll_time64 # define __NR_ppoll_time64 __NR_ppoll #endif return INLINE_SYSCALL_CALL (ppoll_time64, fds, nfds, NULL, NULL, 0); } It avoids a lot of boilerplate code to add the internal symbol.