Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rxrpc: Improve jumbo packet counting

Improve the information stored about jumbo packets so that we don't need to
reparse them so much later.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Jeffrey Altman <jaltman@auristor.com>

+30 -12
+7 -3
net/rxrpc/ar-internal.h
··· 185 185 * - max 48 bytes (struct sk_buff::cb) 186 186 */ 187 187 struct rxrpc_skb_priv { 188 - union { 189 - u8 nr_jumbo; /* Number of jumbo subpackets */ 190 - }; 188 + u8 nr_subpackets; /* Number of subpackets */ 189 + u8 rx_flags; /* Received packet flags */ 190 + #define RXRPC_SKB_INCL_LAST 0x01 /* - Includes last packet */ 191 191 union { 192 192 int remain; /* amount of space remaining for next write */ 193 + 194 + /* List of requested ACKs on subpackets */ 195 + unsigned long rx_req_ack[(RXRPC_MAX_NR_JUMBO + BITS_PER_LONG - 1) / 196 + BITS_PER_LONG]; 193 197 }; 194 198 195 199 struct rxrpc_host_header hdr; /* RxRPC packet header from this packet */
+14 -9
net/rxrpc/input.c
··· 347 347 } 348 348 349 349 /* 350 - * Scan a jumbo packet to validate its structure and to work out how many 350 + * Scan a data packet to validate its structure and to work out how many 351 351 * subpackets it contains. 352 352 * 353 353 * A jumbo packet is a collection of consecutive packets glued together with ··· 358 358 * the last are RXRPC_JUMBO_DATALEN in size. The last subpacket may be of any 359 359 * size. 360 360 */ 361 - static bool rxrpc_validate_jumbo(struct sk_buff *skb) 361 + static bool rxrpc_validate_data(struct sk_buff *skb) 362 362 { 363 363 struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 364 364 unsigned int offset = sizeof(struct rxrpc_wire_header); 365 365 unsigned int len = skb->len; 366 - int nr_jumbo = 1; 367 366 u8 flags = sp->hdr.flags; 368 367 369 - do { 370 - nr_jumbo++; 368 + for (;;) { 369 + if (flags & RXRPC_REQUEST_ACK) 370 + __set_bit(sp->nr_subpackets, sp->rx_req_ack); 371 + sp->nr_subpackets++; 372 + 373 + if (!(flags & RXRPC_JUMBO_PACKET)) 374 + break; 375 + 371 376 if (len - offset < RXRPC_JUMBO_SUBPKTLEN) 372 377 goto protocol_error; 373 378 if (flags & RXRPC_LAST_PACKET) ··· 381 376 if (skb_copy_bits(skb, offset, &flags, 1) < 0) 382 377 goto protocol_error; 383 378 offset += sizeof(struct rxrpc_jumbo_header); 384 - } while (flags & RXRPC_JUMBO_PACKET); 379 + } 385 380 386 - sp->nr_jumbo = nr_jumbo; 381 + if (flags & RXRPC_LAST_PACKET) 382 + sp->rx_flags |= RXRPC_SKB_INCL_LAST; 387 383 return true; 388 384 389 385 protocol_error: ··· 1243 1237 if (sp->hdr.callNumber == 0 || 1244 1238 sp->hdr.seq == 0) 1245 1239 goto bad_message; 1246 - if (sp->hdr.flags & RXRPC_JUMBO_PACKET && 1247 - !rxrpc_validate_jumbo(skb)) 1240 + if (!rxrpc_validate_data(skb)) 1248 1241 goto bad_message; 1249 1242 break; 1250 1243
+9
net/rxrpc/protocol.h
··· 89 89 #define RXRPC_JUMBO_DATALEN 1412 /* non-terminal jumbo packet data length */ 90 90 #define RXRPC_JUMBO_SUBPKTLEN (RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header)) 91 91 92 + /* 93 + * The maximum number of subpackets that can possibly fit in a UDP packet is: 94 + * 95 + * ((max_IP - IP_hdr - UDP_hdr) / RXRPC_JUMBO_SUBPKTLEN) + 1 96 + * = ((65535 - 28 - 28) / 1416) + 1 97 + * = 46 non-terminal packets and 1 terminal packet. 98 + */ 99 + #define RXRPC_MAX_NR_JUMBO 47 100 + 92 101 /*****************************************************************************/ 93 102 /* 94 103 * on-the-wire Rx ACK packet data payload