rxrpc: Add a kvec[] to the rxrpc_txbuf struct
authorDavid Howells <dhowells@redhat.com>
Mon, 29 Jan 2024 23:07:43 +0000 (23:07 +0000)
committerDavid Howells <dhowells@redhat.com>
Thu, 29 Feb 2024 15:49:59 +0000 (15:49 +0000)
Add a kvec[] to the rxrpc_txbuf struct to point to the contributory buffers
for a packet.  Start with just a single element for now, but this will be
expanded later.

Make the ACK sending function use it, which means that rxrpc_fill_out_ack()
doesn't need to return the size of the sack table, padding and trailer.

Make the data sending code use it, both in where sendmsg() packages code up
into txbufs and where those txbufs are transmitted.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: "David S. Miller" <davem@davemloft.net>
cc: Eric Dumazet <edumazet@google.com>
cc: Jakub Kicinski <kuba@kernel.org>
cc: Paolo Abeni <pabeni@redhat.com>
cc: linux-afs@lists.infradead.org
cc: netdev@vger.kernel.org

net/rxrpc/ar-internal.h
net/rxrpc/output.c
net/rxrpc/sendmsg.c
net/rxrpc/txbuf.c

index c9a2882627aace76ee3b67408aef2cdbf9ea5beb..c6731f43a2d57a1334616e822f26e3a5d6dca398 100644 (file)
@@ -805,6 +805,8 @@ struct rxrpc_txbuf {
 #define RXRPC_TXBUF_RESENT     0x100           /* Set if has been resent */
        __be16                  cksum;          /* Checksum to go in header */
        u8 /*enum rxrpc_propose_ack_trace*/ ack_why;    /* If ack, why */
+       u8                      nr_kvec;
+       struct kvec             kvec[1];
        struct {
                /* The packet for encrypting and DMA'ing.  We align it such
                 * that data[] aligns correctly for any crypto blocksize.
index e2c9e645fcfb9d7f8646d86f061e54ca2bfc5641..f2b10c3e4cc26b9927ed6614f19295194aed10c5 100644 (file)
@@ -77,10 +77,10 @@ static void rxrpc_set_keepalive(struct rxrpc_call *call)
 /*
  * Fill out an ACK packet.
  */
-static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn,
-                                struct rxrpc_call *call,
-                                struct rxrpc_txbuf *txb,
-                                u16 *_rwind)
+static void rxrpc_fill_out_ack(struct rxrpc_connection *conn,
+                              struct rxrpc_call *call,
+                              struct rxrpc_txbuf *txb,
+                              u16 *_rwind)
 {
        struct rxrpc_acktrailer trailer;
        unsigned int qsize, sack, wrap, to;
@@ -134,7 +134,9 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn,
        *ackp++ = 0;
        *ackp++ = 0;
        memcpy(ackp, &trailer, sizeof(trailer));
-       return txb->ack.nAcks + 3 + sizeof(trailer);
+       txb->kvec[0].iov_len = sizeof(txb->wire) +
+               sizeof(txb->ack) + txb->ack.nAcks + 3 + sizeof(trailer);
+       txb->len = txb->kvec[0].iov_len;
 }
 
 /*
@@ -187,8 +189,6 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb)
 {
        struct rxrpc_connection *conn;
        struct msghdr msg;
-       struct kvec iov[1];
-       size_t len, n;
        int ret, rtt_slot = -1;
        u16 rwind;
 
@@ -207,13 +207,7 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb)
                txb->flags |= RXRPC_REQUEST_ACK;
        txb->wire.flags = txb->flags & RXRPC_TXBUF_WIRE_FLAGS;
 
-       n = rxrpc_fill_out_ack(conn, call, txb, &rwind);
-       if (n == 0)
-               return 0;
-
-       iov[0].iov_base = &txb->wire;
-       iov[0].iov_len  = sizeof(txb->wire) + sizeof(txb->ack) + n;
-       len = iov[0].iov_len;
+       rxrpc_fill_out_ack(conn, call, txb, &rwind);
 
        txb->serial = rxrpc_get_next_serial(conn);
        txb->wire.serial = htonl(txb->serial);
@@ -230,9 +224,9 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb)
        /* Grab the highest received seq as late as possible */
        txb->ack.previousPacket = htonl(call->rx_highest_seq);
 
-       iov_iter_kvec(&msg.msg_iter, WRITE, iov, 1, len);
+       iov_iter_kvec(&msg.msg_iter, WRITE, txb->kvec, txb->nr_kvec, txb->len);
        rxrpc_local_dont_fragment(conn->local, false);
-       ret = do_udp_sendmsg(conn->local->socket, &msg, len);
+       ret = do_udp_sendmsg(conn->local->socket, &msg, txb->len);
        call->peer->last_tx_at = ktime_get_seconds();
        if (ret < 0) {
                trace_rxrpc_tx_fail(call->debug_id, txb->serial, ret,
@@ -327,7 +321,6 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb)
        enum rxrpc_req_ack_trace why;
        enum rxrpc_tx_point frag;
        struct msghdr msg;
-       struct kvec iov[1];
        size_t len;
        int ret, rtt_slot = -1;
 
@@ -342,10 +335,8 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb)
            txb->seq == 1)
                txb->wire.userStatus = RXRPC_USERSTATUS_SERVICE_UPGRADE;
 
-       iov[0].iov_base = &txb->wire;
-       iov[0].iov_len = sizeof(txb->wire) + txb->len;
-       len = iov[0].iov_len;
-       iov_iter_kvec(&msg.msg_iter, WRITE, iov, 1, len);
+       len = txb->kvec[0].iov_len;
+       iov_iter_kvec(&msg.msg_iter, WRITE, txb->kvec, txb->nr_kvec, len);
 
        msg.msg_name = &call->peer->srx.transport;
        msg.msg_namelen = call->peer->srx.transport_len;
index 25c7c1d4f4c6df4f96ab997ff2e0a6ce0fc2cab6..1e81046ea8a6015f1bc9c76c9f46ae3d4b257d62 100644 (file)
@@ -362,7 +362,7 @@ reload:
                        if (!txb)
                                goto maybe_error;
 
-                       txb->offset = offset;
+                       txb->offset = offset + sizeof(struct rxrpc_wire_header);
                        txb->space -= offset;
                        txb->space = min_t(size_t, chunk, txb->space);
                }
@@ -374,8 +374,8 @@ reload:
                        size_t copy = min_t(size_t, txb->space, msg_data_left(msg));
 
                        _debug("add %zu", copy);
-                       if (!copy_from_iter_full(txb->data + txb->offset, copy,
-                                                &msg->msg_iter))
+                       if (!copy_from_iter_full(txb->kvec[0].iov_base + txb->offset,
+                                                copy, &msg->msg_iter))
                                goto efault;
                        _debug("added");
                        txb->space -= copy;
@@ -404,6 +404,8 @@ reload:
                        if (ret < 0)
                                goto out;
 
+                       txb->kvec[0].iov_len += txb->len;
+                       txb->len = txb->kvec[0].iov_len;
                        rxrpc_queue_packet(rx, call, txb, notify_end_tx);
                        txb = NULL;
                }
index 7273615afe94dea9a8ff3e96547374a48b378341..91e96cda6dc70edf2de3df6043ca0adb3825335b 100644 (file)
@@ -36,6 +36,9 @@ struct rxrpc_txbuf *rxrpc_alloc_txbuf(struct rxrpc_call *call, u8 packet_type,
                txb->seq                = call->tx_prepared + 1;
                txb->serial             = 0;
                txb->cksum              = 0;
+               txb->nr_kvec            = 1;
+               txb->kvec[0].iov_base   = &txb->wire;
+               txb->kvec[0].iov_len    = sizeof(txb->wire);
                txb->wire.epoch         = htonl(call->conn->proto.epoch);
                txb->wire.cid           = htonl(call->cid);
                txb->wire.callNumber    = htonl(call->call_id);