This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCHv2] Call direct system calls for socket operations
- From: Rajalakshmi Srinivasaraghavan <raji at linux dot vnet dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Cc: sjmunroe at us dot ibm dot com, Rajalakshmi Srinivasaraghavan <raji at linux dot vnet dot ibm dot com>
- Date: Thu, 2 Jul 2015 15:23:33 +0530
- Subject: [PATCHv2] Call direct system calls for socket operations
- Authentication-results: sourceware.org; auth=none
Explicit system calls for the socket operations were added in Linux kernel
in commit 86250b9d12ca for powerpc. This patch make use of those instead of
calling socketcall to save number of cycles on networking syscalls.
2015-07-02 Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/kernel-features.h: Define new macros.
* sysdeps/unix/sysv/linux/accept.c: Call direct system call.
* sysdeps/unix/sysv/linux/bind.c: Call direct system call.
* sysdeps/unix/sysv/linux/connect.c: Call direct system call.
* sysdeps/unix/sysv/linux/getpeername.c: Call direct system call.
* sysdeps/unix/sysv/linux/getsockname.c: Call direct system call.
* sysdeps/unix/sysv/linux/getsockopt.c: Call direct system call.
* sysdeps/unix/sysv/linux/listen.c: Call direct system call.
* sysdeps/unix/sysv/linux/recv.c: Call direct system call.
* sysdeps/unix/sysv/linux/recvfrom.c: Call direct system call.
* sysdeps/unix/sysv/linux/recvmsg.c: Call direct system call.
* sysdeps/unix/sysv/linux/send.c: Call direct system call.
* sysdeps/unix/sysv/linux/sendmsg.c: Call direct system call.
* sysdeps/unix/sysv/linux/sendto.c: Call direct system call.
* sysdeps/unix/sysv/linux/setsockopt.c: Call direct system call.
* sysdeps/unix/sysv/linux/shutdown.c: Call direct system call.
* sysdeps/unix/sysv/linux/socket.c: Call direct system call.
* sysdeps/unix/sysv/linux/socketpair.c: Call direct system call.
---
sysdeps/unix/sysv/linux/accept.c | 10 ++++++++++
sysdeps/unix/sysv/linux/bind.c | 10 ++++++++++
sysdeps/unix/sysv/linux/connect.c | 10 ++++++++++
sysdeps/unix/sysv/linux/getpeername.c | 10 ++++++++++
sysdeps/unix/sysv/linux/getsockname.c | 10 ++++++++++
sysdeps/unix/sysv/linux/getsockopt.c | 10 ++++++++++
sysdeps/unix/sysv/linux/listen.c | 10 ++++++++++
sysdeps/unix/sysv/linux/powerpc/kernel-features.h | 21 +++++++++++++++++++++
sysdeps/unix/sysv/linux/recv.c | 10 ++++++++++
sysdeps/unix/sysv/linux/recvfrom.c | 12 ++++++++++++
sysdeps/unix/sysv/linux/recvmsg.c | 10 ++++++++++
sysdeps/unix/sysv/linux/send.c | 10 ++++++++++
sysdeps/unix/sysv/linux/sendmsg.c | 10 ++++++++++
sysdeps/unix/sysv/linux/sendto.c | 12 ++++++++++++
sysdeps/unix/sysv/linux/setsockopt.c | 10 ++++++++++
sysdeps/unix/sysv/linux/shutdown.c | 10 ++++++++++
sysdeps/unix/sysv/linux/socket.c | 10 ++++++++++
sysdeps/unix/sysv/linux/socketpair.c | 10 ++++++++++
18 files changed, 195 insertions(+)
diff --git a/sysdeps/unix/sysv/linux/accept.c b/sysdeps/unix/sysv/linux/accept.c
index 72d42a7..5a0b6fe 100644
--- a/sysdeps/unix/sysv/linux/accept.c
+++ b/sysdeps/unix/sysv/linux/accept.c
@@ -21,11 +21,21 @@
#include <sysdep-cancel.h>
#include <socketcall.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#if defined __ASSUME_ACCEPT_SYSCALL && defined __NR_accept
+int
+__libc_accept (int fd, __SOCKADDR_ARG addr, socklen_t *len)
+{
+ return SYSCALL_CANCEL (accept, fd, addr.__sockaddr__, len);
+}
+#else
int
__libc_accept (int fd, __SOCKADDR_ARG addr, socklen_t *len)
{
return SOCKETCALL_CANCEL (accept, fd, addr.__sockaddr__, len);
}
+#endif
weak_alias (__libc_accept, accept)
libc_hidden_def (accept)
diff --git a/sysdeps/unix/sysv/linux/bind.c b/sysdeps/unix/sysv/linux/bind.c
index db72df6..05a451c 100644
--- a/sysdeps/unix/sysv/linux/bind.c
+++ b/sysdeps/unix/sysv/linux/bind.c
@@ -20,10 +20,20 @@
#include <sys/socket.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_BIND_SYSCALL && defined __NR_bind
+int
+__bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+{
+ return INLINE_SYSCALL (bind, 3, fd, addr.__sockaddr__, len);
+}
+#else
int
__bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
{
return SOCKETCALL (bind, fd, addr.__sockaddr__, len, 0, 0, 0);
}
+#endif
weak_alias (__bind, bind)
diff --git a/sysdeps/unix/sysv/linux/connect.c b/sysdeps/unix/sysv/linux/connect.c
index dd17e8c..dee2a49 100644
--- a/sysdeps/unix/sysv/linux/connect.c
+++ b/sysdeps/unix/sysv/linux/connect.c
@@ -21,12 +21,22 @@
#include <sysdep-cancel.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_CONNECT_SYSCALL && defined __NR_connect
+int
+__libc_connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+{
+ return SYSCALL_CANCEL (connect, fd, addr.__sockaddr__, len);
+}
+#else
int
__libc_connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
{
return SOCKETCALL_CANCEL (connect, fd, addr.__sockaddr__, len);
}
+#endif
weak_alias (__libc_connect, connect)
weak_alias (__libc_connect, __connect)
libc_hidden_weak (__connect)
diff --git a/sysdeps/unix/sysv/linux/getpeername.c b/sysdeps/unix/sysv/linux/getpeername.c
index 05fd2e8..996b9fc 100644
--- a/sysdeps/unix/sysv/linux/getpeername.c
+++ b/sysdeps/unix/sysv/linux/getpeername.c
@@ -20,10 +20,20 @@
#include <sys/socket.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_GETPEERNAME_SYSCALL && defined __NR_getpeername
+int
+__getpeername (int fd, __SOCKADDR_ARG addr, socklen_t *len)
+{
+ return INLINE_SYSCALL (getpeername, 3, fd, addr.__sockaddr__, len);
+}
+#else
int
__getpeername (int fd, __SOCKADDR_ARG addr, socklen_t *len)
{
return SOCKETCALL (getpeername, fd, addr.__sockaddr__, len);
}
+#endif
weak_alias (__getpeername, getpeername)
diff --git a/sysdeps/unix/sysv/linux/getsockname.c b/sysdeps/unix/sysv/linux/getsockname.c
index 6c84ace..66c7edb 100644
--- a/sysdeps/unix/sysv/linux/getsockname.c
+++ b/sysdeps/unix/sysv/linux/getsockname.c
@@ -20,10 +20,20 @@
#include <sys/socket.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_GETSOCKNAME_SYSCALL && defined __NR_getsockname
+int
+__getsockname (int fd, __SOCKADDR_ARG addr, socklen_t *len)
+{
+ return INLINE_SYSCALL (getsockname, 3, fd, addr.__sockaddr__, len);
+}
+#else
int
__getsockname (int fd, __SOCKADDR_ARG addr, socklen_t *len)
{
return SOCKETCALL (getsockname, fd, addr.__sockaddr__, len);
}
+#endif
weak_alias (__getsockname, getsockname)
diff --git a/sysdeps/unix/sysv/linux/getsockopt.c b/sysdeps/unix/sysv/linux/getsockopt.c
index ba5681b..3999b7b 100644
--- a/sysdeps/unix/sysv/linux/getsockopt.c
+++ b/sysdeps/unix/sysv/linux/getsockopt.c
@@ -20,10 +20,20 @@
#include <sys/socket.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_GETSOCKOPT_SYSCALL && defined __NR_getsockopt
+int
+__getsockopt (int fd, int level, int optname, void *optval, socklen_t *len)
+{
+ return INLINE_SYSCALL (getsockopt, 5, fd, level, optname, optval, len);
+}
+#else
int
__getsockopt (int fd, int level, int optname, void *optval, socklen_t *len)
{
return SOCKETCALL (getsockopt, fd, level, optname, optval, len);
}
+#endif
weak_alias (__getsockopt, getsockopt)
diff --git a/sysdeps/unix/sysv/linux/listen.c b/sysdeps/unix/sysv/linux/listen.c
index 2e387a4..2d040b3 100644
--- a/sysdeps/unix/sysv/linux/listen.c
+++ b/sysdeps/unix/sysv/linux/listen.c
@@ -20,10 +20,20 @@
#include <sys/socket.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_LISTEN_SYSCALL && defined __NR_listen
+int
+listen (int fd, int backlog)
+{
+ return INLINE_SYSCALL (listen, 2, fd, backlog);
+}
+#else
int
listen (int fd, int backlog)
{
return SOCKETCALL (listen, fd, backlog);
}
+#endif
weak_alias (listen, __listen);
diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel-features.h b/sysdeps/unix/sysv/linux/powerpc/kernel-features.h
index 6d93491..46bd53f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/powerpc/kernel-features.h
@@ -36,6 +36,27 @@
#endif
#define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL 1
+/* New syscalls added for PowerPC in 2.6.37. */
+#if __LINUX_KERNEL_VERSION >= 0x020625
+# define __ASSUME_SOCKET_SYSCALL 1
+# define __ASSUME_BIND_SYSCALL 1
+# define __ASSUME_CONNECT_SYSCALL 1
+# define __ASSUME_LISTEN_SYSCALL 1
+# define __ASSUME_ACCEPT_SYSCALL 1
+# define __ASSUME_GETSOCKNAME_SYSCALL 1
+# define __ASSUME_GETPEERNAME_SYSCALL 1
+# define __ASSUME_SOCKETPAIR_SYSCALL 1
+# define __ASSUME_SEND_SYSCALL 1
+# define __ASSUME_SENDTO_SYSCALL 1
+# define __ASSUME_RECV_SYSCALL 1
+# define __ASSUME_RECVFROM_SYSCALL 1
+# define __ASSUME_SHUTDOWN_SYSCALL 1
+# define __ASSUME_GETSOCKOPT_SYSCALL 1
+# define __ASSUME_SETSOCKOPT_SYSCALL 1
+# define __ASSUME_SENDMSG_SYSCALL 1
+# define __ASSUME_RECVMSG_SYSCALL 1
+#endif
+
#include_next <kernel-features.h>
/* PowerPC64 IPC is always 64-bit and does not use __IPC_64. */
diff --git a/sysdeps/unix/sysv/linux/recv.c b/sysdeps/unix/sysv/linux/recv.c
index cd2bc1e..934a692 100644
--- a/sysdeps/unix/sysv/linux/recv.c
+++ b/sysdeps/unix/sysv/linux/recv.c
@@ -21,12 +21,22 @@
#include <sysdep-cancel.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_RECV_SYSCALL && defined __NR_recv
+ssize_t
+__libc_recv (int fd, void *buf, size_t len, int flags)
+{
+ return SYSCALL_CANCEL (recv, fd, buf, len, flags);
+}
+#else
ssize_t
__libc_recv (int fd, void *buf, size_t len, int flags)
{
return SOCKETCALL_CANCEL (recv, fd, buf, len, flags);
}
+#endif
weak_alias (__libc_recv, recv)
weak_alias (__libc_recv, __recv)
libc_hidden_weak (__recv)
diff --git a/sysdeps/unix/sysv/linux/recvfrom.c b/sysdeps/unix/sysv/linux/recvfrom.c
index 90eb40d..0918ced 100644
--- a/sysdeps/unix/sysv/linux/recvfrom.c
+++ b/sysdeps/unix/sysv/linux/recvfrom.c
@@ -21,7 +21,18 @@
#include <sysdep-cancel.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_RECVFROM_SYSCALL && defined __NR_recvfrom
+ssize_t
+__libc_recvfrom (int fd, void *buf, size_t len, int flags,
+ __SOCKADDR_ARG addr, socklen_t *addrlen)
+{
+ return SYSCALL_CANCEL (recvfrom, fd, buf, len, flags, addr.__sockaddr__,
+ addrlen);
+}
+#else
ssize_t
__libc_recvfrom (int fd, void *buf, size_t len, int flags,
__SOCKADDR_ARG addr, socklen_t *addrlen)
@@ -29,5 +40,6 @@ __libc_recvfrom (int fd, void *buf, size_t len, int flags,
return SOCKETCALL_CANCEL (recvfrom, fd, buf, len, flags, addr.__sockaddr__,
addrlen);
}
+#endif
weak_alias (__libc_recvfrom, recvfrom)
weak_alias (__libc_recvfrom, __recvfrom)
diff --git a/sysdeps/unix/sysv/linux/recvmsg.c b/sysdeps/unix/sysv/linux/recvmsg.c
index cd7c9ca..4db81db 100644
--- a/sysdeps/unix/sysv/linux/recvmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmsg.c
@@ -21,11 +21,21 @@
#include <sysdep-cancel.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_RECVMSG_SYSCALL && defined __NR_recvmsg
+ssize_t
+__libc_recvmsg (int fd, struct msghdr *msg, int flags)
+{
+ return SYSCALL_CANCEL (recvmsg, fd, msg, flags);
+}
+#else
ssize_t
__libc_recvmsg (int fd, struct msghdr *msg, int flags)
{
return SOCKETCALL_CANCEL (recvmsg, fd, msg, flags);
}
+#endif
weak_alias (__libc_recvmsg, recvmsg)
weak_alias (__libc_recvmsg, __recvmsg)
diff --git a/sysdeps/unix/sysv/linux/send.c b/sysdeps/unix/sysv/linux/send.c
index f87ea86..49ac7b3 100644
--- a/sysdeps/unix/sysv/linux/send.c
+++ b/sysdeps/unix/sysv/linux/send.c
@@ -21,12 +21,22 @@
#include <sysdep-cancel.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_SEND_SYSCALL && defined __NR_send
+ssize_t
+__libc_send (int fd, const void *buf, size_t len, int flags)
+{
+ return SYSCALL_CANCEL (send, fd, buf, len, flags);
+}
+#else
ssize_t
__libc_send (int fd, const void *buf, size_t len, int flags)
{
return SOCKETCALL_CANCEL (send, fd, buf, len, flags);
}
+#endif
weak_alias (__libc_send, send)
weak_alias (__libc_send, __send)
libc_hidden_def (__send)
diff --git a/sysdeps/unix/sysv/linux/sendmsg.c b/sysdeps/unix/sysv/linux/sendmsg.c
index e69ac3e..13f60bc 100644
--- a/sysdeps/unix/sysv/linux/sendmsg.c
+++ b/sysdeps/unix/sysv/linux/sendmsg.c
@@ -21,11 +21,21 @@
#include <sysdep-cancel.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_SENDMSG_SYSCALL && defined __NR_sendmsg
+ssize_t
+__libc_sendmsg (int fd, const struct msghdr *msg, int flags)
+{
+ return SYSCALL_CANCEL (sendmsg, fd, msg, flags);
+}
+#else
ssize_t
__libc_sendmsg (int fd, const struct msghdr *msg, int flags)
{
return SOCKETCALL_CANCEL (sendmsg, fd, msg, flags);
}
+#endif
weak_alias (__libc_sendmsg, sendmsg)
weak_alias (__libc_sendmsg, __sendmsg)
diff --git a/sysdeps/unix/sysv/linux/sendto.c b/sysdeps/unix/sysv/linux/sendto.c
index d2896a6..649c88d 100644
--- a/sysdeps/unix/sysv/linux/sendto.c
+++ b/sysdeps/unix/sysv/linux/sendto.c
@@ -21,7 +21,18 @@
#include <sysdep-cancel.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_SENDTO_SYSCALL && defined __NR_sendto
+ssize_t
+__libc_sendto (int fd, const void *buf, size_t len, int flags,
+ __CONST_SOCKADDR_ARG addr, socklen_t addrlen)
+{
+ return SYSCALL_CANCEL (sendto, fd, buf, len, flags, addr.__sockaddr__,
+ addrlen);
+}
+#else
ssize_t
__libc_sendto (int fd, const void *buf, size_t len, int flags,
__CONST_SOCKADDR_ARG addr, socklen_t addrlen)
@@ -29,5 +40,6 @@ __libc_sendto (int fd, const void *buf, size_t len, int flags,
return SOCKETCALL_CANCEL (sendto, fd, buf, len, flags, addr.__sockaddr__,
addrlen);
}
+#endif
weak_alias (__libc_sendto, sendto)
weak_alias (__libc_sendto, __sendto)
diff --git a/sysdeps/unix/sysv/linux/setsockopt.c b/sysdeps/unix/sysv/linux/setsockopt.c
index 626c55b..cc55814 100644
--- a/sysdeps/unix/sysv/linux/setsockopt.c
+++ b/sysdeps/unix/sysv/linux/setsockopt.c
@@ -20,10 +20,20 @@
#include <sys/socket.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_SETSOCKOPT_SYSCALL && defined __NR_setsockopt
+int
+setsockopt (int fd, int level, int optname, const void *optval, socklen_t len)
+{
+ return INLINE_SYSCALL (setsockopt, 5, fd, level, optname, optval, len);
+}
+#else
int
setsockopt (int fd, int level, int optname, const void *optval, socklen_t len)
{
return SOCKETCALL (setsockopt, fd, level, optname, optval, len);
}
+#endif
weak_alias (setsockopt, __setsockopt)
diff --git a/sysdeps/unix/sysv/linux/shutdown.c b/sysdeps/unix/sysv/linux/shutdown.c
index 8b3a3d8..0ec4e5a 100644
--- a/sysdeps/unix/sysv/linux/shutdown.c
+++ b/sysdeps/unix/sysv/linux/shutdown.c
@@ -20,10 +20,20 @@
#include <sys/socket.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_SHUTDOWN_SYSCALL && defined __NR_shutdown
+int
+__shutdown (int fd, int how)
+{
+ return INLINE_SYSCALL (shutdown, 2, fd, how);
+}
+#else
int
__shutdown (int fd, int how)
{
return SOCKETCALL (shutdown, fd, how);
}
+#endif
weak_alias (__shutdown, shutdown)
diff --git a/sysdeps/unix/sysv/linux/socket.c b/sysdeps/unix/sysv/linux/socket.c
index 3b2c7fe..81a2f00 100644
--- a/sysdeps/unix/sysv/linux/socket.c
+++ b/sysdeps/unix/sysv/linux/socket.c
@@ -20,11 +20,21 @@
#include <sys/socket.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_SOCKET_SYSCALL && defined __NR_socket
+int
+__socket (int fd, int type, int domain)
+{
+ return INLINE_SYSCALL (socket, 3, fd, type, domain);
+}
+#else
int
__socket (int fd, int type, int domain)
{
return SOCKETCALL (socket, fd, type, domain);
}
+#endif
libc_hidden_def (__socket)
weak_alias (__socket, socket)
diff --git a/sysdeps/unix/sysv/linux/socketpair.c b/sysdeps/unix/sysv/linux/socketpair.c
index cb70bcf..788137c 100644
--- a/sysdeps/unix/sysv/linux/socketpair.c
+++ b/sysdeps/unix/sysv/linux/socketpair.c
@@ -20,10 +20,20 @@
#include <sys/socket.h>
#include <socketcall.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if defined __ASSUME_SOCKETPAIR_SYSCALL && defined __NR_socketpair
+int
+__socketpair (int domain, int type, int protocol, int sv[2])
+{
+ return INLINE_SYSCALL (socketpair, 4, domain, type, protocol, sv);
+}
+#else
int
__socketpair (int domain, int type, int protocol, int sv[2])
{
return SOCKETCALL (socketpair, domain, type, protocol, sv);
}
+#endif
weak_alias (__socketpair, socketpair)
--
1.8.3.1