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: Simplify sendmmsg code


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
> 


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