Skip to content

Commit ed472b0

Browse files
committed
rxrpc: Call udp_sendmsg() directly
Call udp_sendmsg() and udpv6_sendmsg() directly rather than calling kernel_sendmsg() as the latter assumes we want a kvec-class iterator. However, zerocopy explicitly doesn't work with such an iterator. Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected]
1 parent b6c66c4 commit ed472b0

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

net/ipv6/udp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,6 +1639,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
16391639
err = 0;
16401640
goto out;
16411641
}
1642+
EXPORT_SYMBOL(udpv6_sendmsg);
16421643

16431644
void udpv6_destroy_sock(struct sock *sk)
16441645
{

net/rxrpc/output.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/export.h>
1414
#include <net/sock.h>
1515
#include <net/af_rxrpc.h>
16+
#include <net/udp.h>
1617
#include "ar-internal.h"
1718

1819
struct rxrpc_ack_buffer {
@@ -23,6 +24,19 @@ struct rxrpc_ack_buffer {
2324
struct rxrpc_ackinfo ackinfo;
2425
};
2526

27+
extern int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);
28+
29+
static ssize_t do_udp_sendmsg(struct socket *sk, struct msghdr *msg, size_t len)
30+
{
31+
#if IS_ENABLED(CONFIG_AF_RXRPC_IPV6)
32+
struct sockaddr *sa = msg->msg_name;
33+
34+
if (sa->sa_family == AF_INET6)
35+
return udpv6_sendmsg(sk->sk, msg, len);
36+
#endif
37+
return udp_sendmsg(sk->sk, msg, len);
38+
}
39+
2640
struct rxrpc_abort_buffer {
2741
struct rxrpc_wire_header whdr;
2842
__be32 abort_code;
@@ -258,8 +272,10 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
258272
rtt_slot = rxrpc_begin_rtt_probe(call, serial, rxrpc_rtt_tx_ping);
259273

260274
rxrpc_inc_stat(call->rxnet, stat_tx_ack_send);
261-
ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
262-
conn->params.peer->last_tx_at = ktime_get_seconds();
275+
276+
iov_iter_kvec(&msg.msg_iter, WRITE, iov, 2, len);
277+
ret = do_udp_sendmsg(conn->params.local->socket, &msg, len);
278+
call->peer->last_tx_at = ktime_get_seconds();
263279
if (ret < 0)
264280
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
265281
rxrpc_tx_point_call_ack);
@@ -336,8 +352,8 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call)
336352
serial = atomic_inc_return(&conn->serial);
337353
pkt.whdr.serial = htonl(serial);
338354

339-
ret = kernel_sendmsg(conn->params.local->socket,
340-
&msg, iov, 1, sizeof(pkt));
355+
iov_iter_kvec(&msg.msg_iter, WRITE, iov, 1, sizeof(pkt));
356+
ret = do_udp_sendmsg(conn->params.local->socket, &msg, sizeof(pkt));
341357
conn->params.peer->last_tx_at = ktime_get_seconds();
342358
if (ret < 0)
343359
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
@@ -397,6 +413,7 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
397413
iov[1].iov_base = skb->head;
398414
iov[1].iov_len = skb->len;
399415
len = iov[0].iov_len + iov[1].iov_len;
416+
iov_iter_kvec(&msg.msg_iter, WRITE, iov, 2, len);
400417

401418
msg.msg_name = &call->peer->srx.transport;
402419
msg.msg_namelen = call->peer->srx.transport_len;
@@ -469,7 +486,7 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
469486
* message and update the peer record
470487
*/
471488
rxrpc_inc_stat(call->rxnet, stat_tx_data_send);
472-
ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
489+
ret = do_udp_sendmsg(conn->params.local->socket, &msg, len);
473490
conn->params.peer->last_tx_at = ktime_get_seconds();
474491

475492
up_read(&conn->params.local->defrag_sem);
@@ -545,8 +562,7 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
545562
ip_sock_set_mtu_discover(conn->params.local->socket->sk,
546563
IP_PMTUDISC_DONT);
547564
rxrpc_inc_stat(call->rxnet, stat_tx_data_send_frag);
548-
ret = kernel_sendmsg(conn->params.local->socket, &msg,
549-
iov, 2, len);
565+
ret = do_udp_sendmsg(conn->params.local->socket, &msg, len);
550566
conn->params.peer->last_tx_at = ktime_get_seconds();
551567

552568
ip_sock_set_mtu_discover(conn->params.local->socket->sk,
@@ -632,8 +648,8 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
632648
whdr.flags ^= RXRPC_CLIENT_INITIATED;
633649
whdr.flags &= RXRPC_CLIENT_INITIATED;
634650

635-
ret = kernel_sendmsg(local->socket, &msg,
636-
iov, ioc, size);
651+
iov_iter_kvec(&msg.msg_iter, WRITE, iov, ioc, size);
652+
ret = do_udp_sendmsg(local->socket, &msg, size);
637653
if (ret < 0)
638654
trace_rxrpc_tx_fail(local->debug_id, 0, ret,
639655
rxrpc_tx_point_reject);
@@ -688,7 +704,8 @@ void rxrpc_send_keepalive(struct rxrpc_peer *peer)
688704

689705
_proto("Tx VERSION (keepalive)");
690706

691-
ret = kernel_sendmsg(peer->local->socket, &msg, iov, 2, len);
707+
iov_iter_kvec(&msg.msg_iter, WRITE, iov, 2, len);
708+
ret = do_udp_sendmsg(peer->local->socket, &msg, len);
692709
if (ret < 0)
693710
trace_rxrpc_tx_fail(peer->debug_id, 0, ret,
694711
rxrpc_tx_point_version_keepalive);

0 commit comments

Comments
 (0)