Skip to content

Commit

Permalink
rxrpc: Clone received jumbo subpackets and queue separately
Browse files Browse the repository at this point in the history
Split up received jumbo packets into separate skbuffs by cloning the
original skbuff for each subpacket and setting the offset and length of the
data in that subpacket in the skbuff's private data.  The subpackets are
then placed on the recvmsg queue separately.  The security class then gets
to revise the offset and length to remove its metadata.

If we fail to clone a packet, we just drop it and let the peer resend it.
The original packet gets used for the final subpacket.

This should make it easier to handle parallel decryption of the subpackets.
It also simplifies the handling of lost or misordered packets in the
queuing/buffering loop as the possibility of overlapping jumbo packets no
longer needs to be considered.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
  • Loading branch information
David Howells committed Nov 8, 2022
1 parent faf92e8 commit d4d02d8
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 417 deletions.
12 changes: 5 additions & 7 deletions include/trace/events/rxrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
#define rxrpc_skb_traces \
EM(rxrpc_skb_cleaned, "CLN") \
EM(rxrpc_skb_cloned_jumbo, "CLJ") \
EM(rxrpc_skb_freed, "FRE") \
EM(rxrpc_skb_got, "GOT") \
EM(rxrpc_skb_lost, "*L*") \
Expand Down Expand Up @@ -630,32 +631,29 @@ TRACE_EVENT(rxrpc_transmit,

TRACE_EVENT(rxrpc_rx_data,
TP_PROTO(unsigned int call, rxrpc_seq_t seq,
rxrpc_serial_t serial, u8 flags, u8 anno),
rxrpc_serial_t serial, u8 flags),

TP_ARGS(call, seq, serial, flags, anno),
TP_ARGS(call, seq, serial, flags),

TP_STRUCT__entry(
__field(unsigned int, call )
__field(rxrpc_seq_t, seq )
__field(rxrpc_serial_t, serial )
__field(u8, flags )
__field(u8, anno )
),

TP_fast_assign(
__entry->call = call;
__entry->seq = seq;
__entry->serial = serial;
__entry->flags = flags;
__entry->anno = anno;
),

TP_printk("c=%08x DATA %08x q=%08x fl=%02x a=%02x",
TP_printk("c=%08x DATA %08x q=%08x fl=%02x",
__entry->call,
__entry->serial,
__entry->seq,
__entry->flags,
__entry->anno)
__entry->flags)
);

TRACE_EVENT(rxrpc_rx_ack,
Expand Down
32 changes: 9 additions & 23 deletions net/rxrpc/ar-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,14 @@ struct rxrpc_host_header {
* - max 48 bytes (struct sk_buff::cb)
*/
struct rxrpc_skb_priv {
atomic_t nr_ring_pins; /* Number of rxtx ring pins */
u8 nr_subpackets; /* Number of subpackets */
u8 rx_flags; /* Received packet flags */
#define RXRPC_SKB_INCL_LAST 0x01 /* - Includes last packet */
union {
int remain; /* amount of space remaining for next write */

/* List of requested ACKs on subpackets */
unsigned long rx_req_ack[(RXRPC_MAX_NR_JUMBO + BITS_PER_LONG - 1) /
BITS_PER_LONG];
};

struct rxrpc_host_header hdr; /* RxRPC packet header from this packet */
u16 remain;
u16 offset; /* Offset of data */
u16 len; /* Length of data */
u8 rx_flags; /* Received packet flags */
u8 flags;
#define RXRPC_RX_VERIFIED 0x01

struct rxrpc_host_header hdr; /* RxRPC packet header from this packet */
};

#define rxrpc_skb(__skb) ((struct rxrpc_skb_priv *) &(__skb)->cb)
Expand Down Expand Up @@ -252,16 +247,11 @@ struct rxrpc_security {
int (*secure_packet)(struct rxrpc_call *, struct sk_buff *, size_t);

/* verify the security on a received packet */
int (*verify_packet)(struct rxrpc_call *, struct sk_buff *,
unsigned int, unsigned int, rxrpc_seq_t, u16);
int (*verify_packet)(struct rxrpc_call *, struct sk_buff *);

/* Free crypto request on a call */
void (*free_call_crypto)(struct rxrpc_call *);

/* Locate the data in a received packet that has been verified. */
void (*locate_data)(struct rxrpc_call *, struct sk_buff *,
unsigned int *, unsigned int *);

/* issue a challenge */
int (*issue_challenge)(struct rxrpc_connection *);

Expand Down Expand Up @@ -628,7 +618,6 @@ struct rxrpc_call {
int debug_id; /* debug ID for printks */
unsigned short rx_pkt_offset; /* Current recvmsg packet offset */
unsigned short rx_pkt_len; /* Current recvmsg packet len */
bool rx_pkt_last; /* Current recvmsg packet is last */

/* Rx/Tx circular buffer, depending on phase.
*
Expand All @@ -652,8 +641,6 @@ struct rxrpc_call {
#define RXRPC_TX_ANNO_LAST 0x04
#define RXRPC_TX_ANNO_RESENT 0x08

#define RXRPC_RX_ANNO_SUBPACKET 0x3f /* Subpacket number in jumbogram */
#define RXRPC_RX_ANNO_VERIFIED 0x80 /* Set if verified and decrypted */
rxrpc_seq_t tx_hard_ack; /* Dead slot in buffer; the first transmitted but
* not hard-ACK'd packet follows this.
*/
Expand Down Expand Up @@ -681,7 +668,6 @@ struct rxrpc_call {
rxrpc_serial_t rx_serial; /* Highest serial received for this call */
u8 rx_winsize; /* Size of Rx window */
u8 tx_winsize; /* Maximum size of Tx window */
u8 nr_jumbo_bad; /* Number of jumbo dups/exceeds-windows */

spinlock_t input_lock; /* Lock for packet input to this call */

Expand Down
Loading

0 comments on commit d4d02d8

Please sign in to comment.