From: David Howells <dhowells@redhat.com>
To: netdev@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>,
Marc Dionne <marc.dionne@auristor.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
linux-afs@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: [PATCH net-next 13/21] rxrpc: Use rxrpc_txbuf::kvec[0] instead of rxrpc_txbuf::wire
Date: Fri, 1 Mar 2024 16:37:45 +0000 [thread overview]
Message-ID: <20240301163807.385573-14-dhowells@redhat.com> (raw)
In-Reply-To: <20240301163807.385573-1-dhowells@redhat.com>
Use rxrpc_txbuf::kvec[0] instead of rxrpc_txbuf::wire to gain access to the
Rx protocol header. In future, the wire header will be stored in a page
frag, not in the rxrpc_txbuf struct making it possible to use
MSG_SPLICE_PAGES when sending it.
Similarly, access the ack header as being immediately after the wire header
when filling out an ACK packet.
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 | 5 +--
net/rxrpc/output.c | 80 ++++++++++++++++++++---------------------
net/rxrpc/txbuf.c | 27 +++++++-------
3 files changed, 57 insertions(+), 55 deletions(-)
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index a8795ef0d669..9ea4e7e9d9f7 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -804,6 +804,7 @@ struct rxrpc_txbuf {
#define RXRPC_TXBUF_WIRE_FLAGS 0xff /* The wire protocol flags */
#define RXRPC_TXBUF_RESENT 0x100 /* Set if has been resent */
__be16 cksum; /* Checksum to go in header */
+ unsigned short ack_rwind; /* ACK receive window */
u8 /*enum rxrpc_propose_ack_trace*/ ack_why; /* If ack, why */
u8 nr_kvec;
struct kvec kvec[1];
@@ -812,11 +813,11 @@ struct rxrpc_txbuf {
* that data[] aligns correctly for any crypto blocksize.
*/
u8 pad[64 - sizeof(struct rxrpc_wire_header)];
- struct rxrpc_wire_header wire; /* Network-ready header */
+ struct rxrpc_wire_header _wire; /* Network-ready header */
union {
u8 data[RXRPC_JUMBO_DATALEN]; /* Data packet */
struct {
- struct rxrpc_ackpacket ack;
+ struct rxrpc_ackpacket _ack;
DECLARE_FLEX_ARRAY(u8, acks);
};
};
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index ec9ae9c6c492..b84b40562e5b 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -77,11 +77,13 @@ static void rxrpc_set_keepalive(struct rxrpc_call *call)
/*
* Fill out an ACK packet.
*/
-static void rxrpc_fill_out_ack(struct rxrpc_connection *conn,
- struct rxrpc_call *call,
+static void rxrpc_fill_out_ack(struct rxrpc_call *call,
struct rxrpc_txbuf *txb,
- u16 *_rwind)
+ u8 ack_reason,
+ rxrpc_serial_t serial)
{
+ struct rxrpc_wire_header *whdr = txb->kvec[0].iov_base;
+ struct rxrpc_ackpacket *ack = (struct rxrpc_ackpacket *)(whdr + 1);
struct rxrpc_acktrailer trailer;
unsigned int qsize, sack, wrap, to;
rxrpc_seq_t window, wtop;
@@ -97,15 +99,24 @@ static void rxrpc_fill_out_ack(struct rxrpc_connection *conn,
window = call->ackr_window;
wtop = call->ackr_wtop;
sack = call->ackr_sack_base % RXRPC_SACK_SIZE;
- txb->ack.firstPacket = htonl(window);
- txb->ack.nAcks = wtop - window;
+
+ whdr->seq = 0;
+ whdr->type = RXRPC_PACKET_TYPE_ACK;
+ txb->flags |= RXRPC_SLOW_START_OK;
+ ack->bufferSpace = 0;
+ ack->maxSkew = 0;
+ ack->firstPacket = htonl(window);
+ ack->previousPacket = htonl(call->rx_highest_seq);
+ ack->serial = htonl(serial);
+ ack->reason = ack_reason;
+ ack->nAcks = wtop - window;
if (after(wtop, window)) {
wrap = RXRPC_SACK_SIZE - sack;
- to = min_t(unsigned int, txb->ack.nAcks, RXRPC_SACK_SIZE);
+ to = min_t(unsigned int, ack->nAcks, RXRPC_SACK_SIZE);
- if (sack + txb->ack.nAcks <= RXRPC_SACK_SIZE) {
- memcpy(txb->acks, call->ackr_sack_table + sack, txb->ack.nAcks);
+ if (sack + ack->nAcks <= RXRPC_SACK_SIZE) {
+ memcpy(txb->acks, call->ackr_sack_table + sack, ack->nAcks);
} else {
memcpy(txb->acks, call->ackr_sack_table + sack, wrap);
memcpy(txb->acks + wrap, call->ackr_sack_table,
@@ -115,16 +126,16 @@ static void rxrpc_fill_out_ack(struct rxrpc_connection *conn,
ackp += to;
} else if (before(wtop, window)) {
pr_warn("ack window backward %x %x", window, wtop);
- } else if (txb->ack.reason == RXRPC_ACK_DELAY) {
- txb->ack.reason = RXRPC_ACK_IDLE;
+ } else if (ack->reason == RXRPC_ACK_DELAY) {
+ ack->reason = RXRPC_ACK_IDLE;
}
- mtu = conn->peer->if_mtu;
- mtu -= conn->peer->hdrsize;
+ mtu = call->peer->if_mtu;
+ mtu -= call->peer->hdrsize;
jmax = rxrpc_rx_jumbo_max;
qsize = (window - 1) - call->rx_consumed;
rsize = max_t(int, call->rx_winsize - qsize, 0);
- *_rwind = rsize;
+ txb->ack_rwind = rsize;
trailer.maxMTU = htonl(rxrpc_rx_mtu);
trailer.ifMTU = htonl(mtu);
trailer.rwind = htonl(rsize);
@@ -134,8 +145,7 @@ static void rxrpc_fill_out_ack(struct rxrpc_connection *conn,
*ackp++ = 0;
*ackp++ = 0;
memcpy(ackp, &trailer, sizeof(trailer));
- txb->kvec[0].iov_len = sizeof(txb->wire) +
- sizeof(txb->ack) + txb->ack.nAcks + 3 + sizeof(trailer);
+ txb->kvec[0].iov_len += sizeof(*ack) + ack->nAcks + 3 + sizeof(trailer);
txb->len = txb->kvec[0].iov_len;
}
@@ -187,10 +197,11 @@ static void rxrpc_cancel_rtt_probe(struct rxrpc_call *call,
*/
static int rxrpc_send_ack_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb)
{
+ struct rxrpc_wire_header *whdr = txb->kvec[0].iov_base;
struct rxrpc_connection *conn;
+ struct rxrpc_ackpacket *ack = (struct rxrpc_ackpacket *)(whdr + 1);
struct msghdr msg;
int ret, rtt_slot = -1;
- u16 rwind;
if (test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
return -ECONNRESET;
@@ -203,27 +214,22 @@ static int rxrpc_send_ack_packet(struct rxrpc_call *call, struct rxrpc_txbuf *tx
msg.msg_controllen = 0;
msg.msg_flags = 0;
- if (txb->ack.reason == RXRPC_ACK_PING)
+ if (ack->reason == RXRPC_ACK_PING)
txb->flags |= RXRPC_REQUEST_ACK;
- txb->wire.flags = txb->flags & RXRPC_TXBUF_WIRE_FLAGS;
-
- rxrpc_fill_out_ack(conn, call, txb, &rwind);
+ whdr->flags = txb->flags & RXRPC_TXBUF_WIRE_FLAGS;
txb->serial = rxrpc_get_next_serial(conn);
- txb->wire.serial = htonl(txb->serial);
+ whdr->serial = htonl(txb->serial);
trace_rxrpc_tx_ack(call->debug_id, txb->serial,
- ntohl(txb->ack.firstPacket),
- ntohl(txb->ack.serial), txb->ack.reason, txb->ack.nAcks,
- rwind);
+ ntohl(ack->firstPacket),
+ ntohl(ack->serial), ack->reason, ack->nAcks,
+ txb->ack_rwind);
- if (txb->ack.reason == RXRPC_ACK_PING)
+ if (ack->reason == RXRPC_ACK_PING)
rtt_slot = rxrpc_begin_rtt_probe(call, txb->serial, rxrpc_rtt_tx_ping);
rxrpc_inc_stat(call->rxnet, stat_tx_ack_send);
- /* Grab the highest received seq as late as possible */
- txb->ack.previousPacket = htonl(call->rx_highest_seq);
-
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, txb->len);
@@ -232,7 +238,7 @@ static int rxrpc_send_ack_packet(struct rxrpc_call *call, struct rxrpc_txbuf *tx
trace_rxrpc_tx_fail(call->debug_id, txb->serial, ret,
rxrpc_tx_point_call_ack);
} else {
- trace_rxrpc_tx_packet(call->debug_id, &txb->wire,
+ trace_rxrpc_tx_packet(call->debug_id, whdr,
rxrpc_tx_point_call_ack);
if (txb->flags & RXRPC_REQUEST_ACK)
call->peer->rtt_last_req = ktime_get_real();
@@ -254,6 +260,7 @@ static int rxrpc_send_ack_packet(struct rxrpc_call *call, struct rxrpc_txbuf *tx
void rxrpc_send_ACK(struct rxrpc_call *call, u8 ack_reason,
rxrpc_serial_t serial, enum rxrpc_propose_ack_trace why)
{
+ struct rxrpc_wire_header *whdr;
struct rxrpc_txbuf *txb;
if (test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
@@ -268,18 +275,9 @@ void rxrpc_send_ACK(struct rxrpc_call *call, u8 ack_reason,
return;
}
- txb->ack_why = why;
- txb->wire.seq = 0;
- txb->wire.type = RXRPC_PACKET_TYPE_ACK;
- txb->flags |= RXRPC_SLOW_START_OK;
- txb->ack.bufferSpace = 0;
- txb->ack.maxSkew = 0;
- txb->ack.firstPacket = 0;
- txb->ack.previousPacket = 0;
- txb->ack.serial = htonl(serial);
- txb->ack.reason = ack_reason;
- txb->ack.nAcks = 0;
+ rxrpc_fill_out_ack(call, txb, ack_reason, serial);
+ txb->ack_why = why;
trace_rxrpc_send_ack(call, why, ack_reason, serial);
rxrpc_send_ack_packet(call, txb);
rxrpc_put_txbuf(txb, rxrpc_txbuf_put_ack_tx);
@@ -365,7 +363,7 @@ static void rxrpc_prepare_data_subpacket(struct rxrpc_call *call, struct rxrpc_t
if (test_bit(RXRPC_CONN_PROBING_FOR_UPGRADE, &conn->flags) &&
txb->seq == 1)
- txb->wire.userStatus = RXRPC_USERSTATUS_SERVICE_UPGRADE;
+ whdr->userStatus = RXRPC_USERSTATUS_SERVICE_UPGRADE;
/* If our RTT cache needs working on, request an ACK. Also request
* ACKs if a DATA packet appears to have been lost.
diff --git a/net/rxrpc/txbuf.c b/net/rxrpc/txbuf.c
index 91e96cda6dc7..2e8c5b15a84f 100644
--- a/net/rxrpc/txbuf.c
+++ b/net/rxrpc/txbuf.c
@@ -19,10 +19,13 @@ atomic_t rxrpc_nr_txbuf;
struct rxrpc_txbuf *rxrpc_alloc_txbuf(struct rxrpc_call *call, u8 packet_type,
gfp_t gfp)
{
+ struct rxrpc_wire_header *whdr;
struct rxrpc_txbuf *txb;
txb = kmalloc(sizeof(*txb), gfp);
if (txb) {
+ whdr = &txb->_wire;
+
INIT_LIST_HEAD(&txb->call_link);
INIT_LIST_HEAD(&txb->tx_link);
refcount_set(&txb->ref, 1);
@@ -37,18 +40,18 @@ struct rxrpc_txbuf *rxrpc_alloc_txbuf(struct rxrpc_call *call, u8 packet_type,
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);
- txb->wire.seq = htonl(txb->seq);
- txb->wire.type = packet_type;
- txb->wire.flags = 0;
- txb->wire.userStatus = 0;
- txb->wire.securityIndex = call->security_ix;
- txb->wire._rsvd = 0;
- txb->wire.serviceId = htons(call->dest_srx.srx_service);
+ txb->kvec[0].iov_base = whdr;
+ txb->kvec[0].iov_len = sizeof(*whdr);
+ whdr->epoch = htonl(call->conn->proto.epoch);
+ whdr->cid = htonl(call->cid);
+ whdr->callNumber = htonl(call->call_id);
+ whdr->seq = htonl(txb->seq);
+ whdr->type = packet_type;
+ whdr->flags = 0;
+ whdr->userStatus = 0;
+ whdr->securityIndex = call->security_ix;
+ whdr->_rsvd = 0;
+ whdr->serviceId = htons(call->dest_srx.srx_service);
trace_rxrpc_txbuf(txb->debug_id,
txb->call_debug_id, txb->seq, 1,
next prev parent reply other threads:[~2024-03-01 16:38 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-01 16:37 [PATCH net-next 00/21] rxrpc: Miscellaneous changes and make use of MSG_SPLICE_PAGES David Howells
2024-03-01 16:37 ` [PATCH net-next 01/21] rxrpc: Record the Tx serial in the rxrpc_txbuf and retransmit trace David Howells
2024-03-01 16:37 ` [PATCH net-next 02/21] rxrpc: Convert rxrpc_txbuf::flags into a mask and don't use atomics David Howells
2024-03-01 16:37 ` [PATCH net-next 03/21] rxrpc: Note cksum in txbuf David Howells
2024-03-01 16:37 ` [PATCH net-next 04/21] rxrpc: Fix the names of the fields in the ACK trailer struct David Howells
2024-03-01 16:37 ` [PATCH net-next 05/21] rxrpc: Strip barriers and atomics off of timer tracking David Howells
2024-03-01 16:37 ` [PATCH net-next 06/21] rxrpc: Remove atomic handling on some fields only used in I/O thread David Howells
2024-03-01 16:37 ` [PATCH net-next 07/21] rxrpc: Do lazy DF flag resetting David Howells
2024-03-01 16:37 ` [PATCH net-next 08/21] rxrpc: Merge together DF/non-DF branches of data Tx function David Howells
2024-03-01 16:37 ` [PATCH net-next 09/21] rxrpc: Add a kvec[] to the rxrpc_txbuf struct David Howells
2024-03-01 16:37 ` [PATCH net-next 10/21] rxrpc: Split up the DATA packet transmission function David Howells
2024-03-01 16:37 ` [PATCH net-next 11/21] rxrpc: Don't pick values out of the wire header when setting up security David Howells
2024-03-01 16:37 ` [PATCH net-next 12/21] rxrpc: Move rxrpc_send_ACK() to output.c with rxrpc_send_ack_packet() David Howells
2024-03-01 16:37 ` David Howells [this message]
2024-03-03 5:26 ` [PATCH net-next 13/21] rxrpc: Use rxrpc_txbuf::kvec[0] instead of rxrpc_txbuf::wire Jakub Kicinski
2024-03-01 16:37 ` [PATCH net-next 14/21] rxrpc: Do zerocopy using MSG_SPLICE_PAGES and page frags David Howells
2024-03-01 16:37 ` [PATCH net-next 15/21] rxrpc: Parse received packets before dealing with timeouts David Howells
2024-03-01 16:37 ` [PATCH net-next 16/21] rxrpc: Don't permit resending after all Tx packets acked David Howells
2024-03-01 16:37 ` [PATCH net-next 17/21] rxrpc: Differentiate PING ACK transmission traces David Howells
2024-03-01 16:37 ` [PATCH net-next 18/21] rxrpc: Use ktimes for call timeout tracking and set the timer lazily David Howells
2024-03-03 5:27 ` Jakub Kicinski
2024-03-03 23:58 ` David Howells
2024-03-01 16:37 ` [PATCH net-next 19/21] rxrpc: Record probes after transmission and reduce number of time-gets David Howells
2024-03-01 16:37 ` [PATCH net-next 20/21] rxrpc: Clean up the resend algorithm David Howells
2024-03-01 16:37 ` [PATCH net-next 21/21] rxrpc: Extract useful fields from a received ACK to skb priv data David Howells
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240301163807.385573-14-dhowells@redhat.com \
--to=dhowells@redhat.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-afs@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=marc.dionne@auristor.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).