Commit ff342bdc authored by David Howells's avatar David Howells
Browse files

rxrpc: Add a kvec[] to the rxrpc_txbuf struct



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: default avatarDavid 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
parent 1ac6a853
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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.
+12 −21
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ 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,
static void rxrpc_fill_out_ack(struct rxrpc_connection *conn,
			       struct rxrpc_call *call,
			       struct rxrpc_txbuf *txb,
			       u16 *_rwind)
@@ -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;
+5 −3
Original line number Diff line number Diff line
@@ -362,7 +362,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
			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 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
			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 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
			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;
		}
+3 −0
Original line number Diff line number Diff line
@@ -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);