This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Simplify sendmmsg code
- From: Adhemerval Zanella <adhemerval dot zanella at linaro dot org>
- To: libc-alpha at sourceware dot org
- Date: Tue, 9 May 2017 15:41:45 -0300
- Subject: Re: Simplify sendmmsg code
- Authentication-results: sourceware.org; auth=none
- References: <alpine.DEB.2.20.1705091552540.16186@digraph.polyomino.org.uk>
On 09/05/2017 12:54, Joseph Myers wrote:
> Now we can assume a kernel with sendmmsg support, this patch
> simplifies the implementation to be similar to that for accept4:
> either using socketcall or the syscall according to whether the
> syscall is known to be available, without further fallback
> implementations. The __ASSUME_SENDMMSG macro is kept (now defined
> unconditionally), since it's used in resolv/res_send.c.
I think we can add a sysdeps/posix sendmmsg based on sendmsg so we can
safely remove this macro usage on resolv code. I will work on this
after your patch inclusion.
>
> Tested for x86_64 and x86.
>
> 2017-05-09 Joseph Myers <joseph@codesourcery.com>
>
> * sysdeps/unix/sysv/linux/kernel-features.h
> (__ASSUME_SENDMMSG_SYSCALL): Define unconditionally.
> (__ASSUME_SENDMMSG): Likewise.
> (__ASSUME_SENDMMSG_SOCKETCALL): Remove macro.
> * sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Define using
> sendmmsg syscall if that can be assumed to be present, socketcall
> otherwise, with no fallback for runtime failure.
LGTM, thanks.
>
> diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
> index 74ac627..c9212b4 100644
> --- a/sysdeps/unix/sysv/linux/kernel-features.h
> +++ b/sysdeps/unix/sysv/linux/kernel-features.h
> @@ -105,13 +105,8 @@
>
> /* Support for sendmmsg functionality was added in 3.0. The macros
> defined correspond to those for accept4 and recvmmsg. */
> -#if __LINUX_KERNEL_VERSION >= 0x030000
> -# ifdef __ASSUME_SOCKETCALL
> -# define __ASSUME_SENDMMSG_SOCKETCALL 1
> -# endif
> -# define __ASSUME_SENDMMSG_SYSCALL 1
> -# define __ASSUME_SENDMMSG 1
> -#endif
> +#define __ASSUME_SENDMMSG_SYSCALL 1
> +#define __ASSUME_SENDMMSG 1
>
> /* On most architectures, most socket syscalls are supported for all
> supported kernel versions, but on some socketcall architectures
> diff --git a/sysdeps/unix/sysv/linux/sendmmsg.c b/sysdeps/unix/sysv/linux/sendmmsg.c
> index 2dd0eba..c559623 100644
> --- a/sysdeps/unix/sysv/linux/sendmmsg.c
> +++ b/sysdeps/unix/sysv/linux/sendmmsg.c
> @@ -21,73 +21,22 @@
>
> #include <sysdep-cancel.h>
> #include <sys/syscall.h>
> +#include <socketcall.h>
> #include <kernel-features.h>
>
> -/* Do not use the sendmmsg syscall on socketcall architectures unless
> - it was added at the same time as the socketcall support or can be
> - assumed to be present. */
> -#if defined __ASSUME_SOCKETCALL \
> - && !defined __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL \
> - && !defined __ASSUME_SENDMMSG_SYSCALL
> -# undef __NR_sendmmsg
> -#endif
> -
> -#ifdef __NR_sendmmsg
> -int
> -__sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
> -{
> - return SYSCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
> -}
> -libc_hidden_def (__sendmmsg)
> -weak_alias (__sendmmsg, sendmmsg)
> -#elif defined __NR_socketcall
> -# include <socketcall.h>
> -# ifdef __ASSUME_SENDMMSG_SOCKETCALL
> int
> __sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
> {
> + /* Do not use the sendmmsg syscall on socketcall architectures unless
> + it was added at the same time as the socketcall support or can be
> + assumed to be present. */
> +#if defined __ASSUME_SOCKETCALL \
> + && !defined __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL \
> + && !defined __ASSUME_SENDMMSG_SYSCALL
> return SOCKETCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
> +#else
> + return SYSCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
> +#endif
> }
> -# else
> -static int have_sendmmsg;
> -
> -int
> -__sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
> -{
> - if (__glibc_likely (have_sendmmsg >= 0))
> - {
> - int ret = SOCKETCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
> - /* The kernel returns -EINVAL for unknown socket operations.
> - We need to convert that error to an ENOSYS error. */
> - if (__builtin_expect (ret < 0, 0)
> - && have_sendmmsg == 0
> - && errno == EINVAL)
> - {
> - /* Try another call, this time with an invalid file
> - descriptor and all other parameters cleared. This call
> - will not cause any harm and it will return
> - immediately. */
> - ret = SOCKETCALL_CANCEL (invalid, -1);
> - if (errno == EINVAL)
> - {
> - have_sendmmsg = -1;
> - __set_errno (ENOSYS);
> - }
> - else
> - {
> - have_sendmmsg = 1;
> - __set_errno (EINVAL);
> - }
> - return -1;
> - }
> - return ret;
> - }
> - __set_errno (ENOSYS);
> - return -1;
> -}
> -# endif /* __ASSUME_SENDMMSG_SOCKETCALL */
> libc_hidden_def (__sendmmsg)
> weak_alias (__sendmmsg, sendmmsg)
> -#else
> -# include <socket/sendmmsg.c>
> -#endif
>