aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2019-05-03 11:01:39 -0400
committerDavid S. Miller <davem@davemloft.net>2019-05-05 13:38:04 -0400
commit8c3c447b3cec27cf6f77080f4d157d53b64e9555 (patch)
tree7df6f2b6631f9396a0a159df594fc02de434f387 /net/socket.c
parent97ff7ffb11fe7a859a490771e7ce23f1f335176b (diff)
net: use indirect calls helpers at the socket layer
This avoids an indirect call per {send,recv}msg syscall in the common (IPv6 or IPv4 socket) case. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/net/socket.c b/net/socket.c
index a180e1a9ff23..472fbefa5d9b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -90,6 +90,7 @@
90#include <linux/slab.h> 90#include <linux/slab.h>
91#include <linux/xattr.h> 91#include <linux/xattr.h>
92#include <linux/nospec.h> 92#include <linux/nospec.h>
93#include <linux/indirect_call_wrapper.h>
93 94
94#include <linux/uaccess.h> 95#include <linux/uaccess.h>
95#include <asm/unistd.h> 96#include <asm/unistd.h>
@@ -108,6 +109,13 @@
108#include <net/busy_poll.h> 109#include <net/busy_poll.h>
109#include <linux/errqueue.h> 110#include <linux/errqueue.h>
110 111
112/* proto_ops for ipv4 and ipv6 use the same {recv,send}msg function */
113#if IS_ENABLED(CONFIG_INET)
114#define INDIRECT_CALL_INET4(f, f1, ...) INDIRECT_CALL_1(f, f1, __VA_ARGS__)
115#else
116#define INDIRECT_CALL_INET4(f, f1, ...) f(__VA_ARGS__)
117#endif
118
111#ifdef CONFIG_NET_RX_BUSY_POLL 119#ifdef CONFIG_NET_RX_BUSY_POLL
112unsigned int sysctl_net_busy_read __read_mostly; 120unsigned int sysctl_net_busy_read __read_mostly;
113unsigned int sysctl_net_busy_poll __read_mostly; 121unsigned int sysctl_net_busy_poll __read_mostly;
@@ -645,10 +653,12 @@ EXPORT_SYMBOL(__sock_tx_timestamp);
645 * Sends @msg through @sock, passing through LSM. 653 * Sends @msg through @sock, passing through LSM.
646 * Returns the number of bytes sent, or an error code. 654 * Returns the number of bytes sent, or an error code.
647 */ 655 */
648 656INDIRECT_CALLABLE_DECLARE(int inet_sendmsg(struct socket *, struct msghdr *,
657 size_t));
649static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg) 658static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
650{ 659{
651 int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg)); 660 int ret = INDIRECT_CALL_INET4(sock->ops->sendmsg, inet_sendmsg, sock,
661 msg, msg_data_left(msg));
652 BUG_ON(ret == -EIOCBQUEUED); 662 BUG_ON(ret == -EIOCBQUEUED);
653 return ret; 663 return ret;
654} 664}
@@ -874,11 +884,13 @@ EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops);
874 * Receives @msg from @sock, passing through LSM. Returns the total number 884 * Receives @msg from @sock, passing through LSM. Returns the total number
875 * of bytes received, or an error. 885 * of bytes received, or an error.
876 */ 886 */
877 887INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *,
888 size_t , int ));
878static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, 889static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
879 int flags) 890 int flags)
880{ 891{
881 return sock->ops->recvmsg(sock, msg, msg_data_left(msg), flags); 892 return INDIRECT_CALL_INET4(sock->ops->recvmsg, inet_recvmsg, sock, msg,
893 msg_data_left(msg), flags);
882} 894}
883 895
884int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags) 896int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags)