diff options
author | Paolo Abeni <pabeni@redhat.com> | 2019-05-03 11:01:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-05-05 13:38:04 -0400 |
commit | 8c3c447b3cec27cf6f77080f4d157d53b64e9555 (patch) | |
tree | 7df6f2b6631f9396a0a159df594fc02de434f387 /net/socket.c | |
parent | 97ff7ffb11fe7a859a490771e7ce23f1f335176b (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.c | 20 |
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 |
112 | unsigned int sysctl_net_busy_read __read_mostly; | 120 | unsigned int sysctl_net_busy_read __read_mostly; |
113 | unsigned int sysctl_net_busy_poll __read_mostly; | 121 | unsigned 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 | 656 | INDIRECT_CALLABLE_DECLARE(int inet_sendmsg(struct socket *, struct msghdr *, | |
657 | size_t)); | ||
649 | static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg) | 658 | static 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 | 887 | INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *, | |
888 | size_t , int )); | ||
878 | static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, | 889 | static 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 | ||
884 | int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags) | 896 | int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags) |