1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-07 06:43:00 +03:00

Simplify recvmmsg code.

Now we can assume a kernel with recvmmsg 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.

(In fact further simplification is possible, getting rid of the
__ASSUME_*_SYSCALL_WITH_SOCKETCALL macros now that the minimum kernel
is guaranteed support for all of accept4, recvmmsg, sendmmsg, whether
through syscalls or through socketcall.  I intend to do that for all
of accept4 / recvmmsg / sendmmsg together - so making their
implementations just like those for older socket functions - once the
basic cleanup for 3.2 minimum kernel is done for sendmmsg as well as
recvmmsg.)

Tested for x86_64 and x86.

	* sysdeps/unix/sysv/linux/kernel-features.h
	(__ASSUME_RECVMMSG_SYSCALL): Define unconditionally.
	(__ASSUME_RECVMMSG_SOCKETCALL): Remove macro.
	(__ASSUME_RECVMMSG): Likewise.
	* sysdeps/unix/sysv/linux/recvmmsg.c (recvmmsg): Define using
	recvmmsg syscall if it can be assumed to be present, socketcall
	otherwise, with no fallback for runtime failure.
This commit is contained in:
Joseph Myers
2017-05-09 20:01:01 +00:00
parent 4fc12f0eda
commit 9a45f54310
3 changed files with 21 additions and 69 deletions

View File

@@ -1,3 +1,13 @@
2017-05-09 Joseph Myers <joseph@codesourcery.com>
* sysdeps/unix/sysv/linux/kernel-features.h
(__ASSUME_RECVMMSG_SYSCALL): Define unconditionally.
(__ASSUME_RECVMMSG_SOCKETCALL): Remove macro.
(__ASSUME_RECVMMSG): Likewise.
* sysdeps/unix/sysv/linux/recvmmsg.c (recvmmsg): Define using
recvmmsg syscall if it can be assumed to be present, socketcall
otherwise, with no fallback for runtime failure.
2017-05-09 Paul E. Murphy <murphyp@linux.vnet.ibm.com> 2017-05-09 Paul E. Murphy <murphyp@linux.vnet.ibm.com>
Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com> Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>

View File

@@ -90,13 +90,7 @@
/* Support for recvmmsg functionality was added in 2.6.33. The macros /* Support for recvmmsg functionality was added in 2.6.33. The macros
defined correspond to those for accept4. */ defined correspond to those for accept4. */
#if __LINUX_KERNEL_VERSION >= 0x020621 #define __ASSUME_RECVMMSG_SYSCALL 1
# ifdef __ASSUME_SOCKETCALL
# define __ASSUME_RECVMMSG_SOCKETCALL 1
# endif
# define __ASSUME_RECVMMSG_SYSCALL 1
# define __ASSUME_RECVMMSG 1
#endif
/* statfs fills in f_flags since 2.6.36. */ /* statfs fills in f_flags since 2.6.36. */
#if __LINUX_KERNEL_VERSION >= 0x020624 #if __LINUX_KERNEL_VERSION >= 0x020624

View File

@@ -21,73 +21,21 @@
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <socketcall.h>
#include <kernel-features.h> #include <kernel-features.h>
/* Do not use the recvmmsg syscall on socketcall architectures unless int
recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
struct timespec *tmo)
{
/* Do not use the recvmmsg syscall on socketcall architectures unless
it was added at the same time as the socketcall support or can be it was added at the same time as the socketcall support or can be
assumed to be present. */ assumed to be present. */
#if defined __ASSUME_SOCKETCALL \ #if defined __ASSUME_SOCKETCALL \
&& !defined __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL \ && !defined __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL \
&& !defined __ASSUME_RECVMMSG_SYSCALL && !defined __ASSUME_RECVMMSG_SYSCALL
# undef __NR_recvmmsg
#endif
#ifdef __NR_recvmmsg
int
recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
struct timespec *tmo)
{
return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
}
#elif defined __NR_socketcall
# include <socketcall.h>
# ifdef __ASSUME_RECVMMSG_SOCKETCALL
int
recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
struct timespec *tmo)
{
return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo); return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
}
# else
static int have_recvmmsg;
int
recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
struct timespec *tmo)
{
if (__glibc_likely (have_recvmmsg >= 0))
{
int ret = SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags,
tmo);
/* 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_recvmmsg == 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_recvmmsg = -1;
__set_errno (ENOSYS);
}
else
{
have_recvmmsg = 1;
__set_errno (EINVAL);
}
return -1;
}
return ret;
}
__set_errno (ENOSYS);
return -1;
}
# endif /* __ASSUME_RECVMMSG_SOCKETCALL */
#else #else
# include <socket/recvmmsg.c> return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
#endif #endif
}