aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-09-13 17:36:22 -0400
committerDavid Howells <dhowells@redhat.com>2016-09-13 17:38:45 -0400
commit75e42126399220069ada0ca0e93237993c6afccf (patch)
tree33e6f4d4378ac573346d0b405cc335db93c6830f
parent3432a757b1f889f8c0d33cd9fcabdae172ed812b (diff)
rxrpc: Correctly initialise, limit and transmit call->rx_winsize
call->rx_winsize should be initialised to the sysctl setting and the sysctl setting should be limited to the maximum we want to permit. Further, we need to place this in the ACK info instead of the sysctl setting. Furthermore, discard the idea of accepting the subpackets of a jumbo packet that lie beyond the receive window when the first packet of the jumbo is within the window. Just discard the excess subpackets instead. This allows the receive window to be opened up right to the buffer size less one for the dead slot. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--net/rxrpc/ar-internal.h3
-rw-r--r--net/rxrpc/call_object.c2
-rw-r--r--net/rxrpc/input.c23
-rw-r--r--net/rxrpc/misc.c5
-rw-r--r--net/rxrpc/output.c4
-rw-r--r--net/rxrpc/sysctl.c2
6 files changed, 26 insertions, 13 deletions
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 47c74a581a0f..e78c40b37db5 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -498,6 +498,7 @@ struct rxrpc_call {
498 */ 498 */
499#define RXRPC_RXTX_BUFF_SIZE 64 499#define RXRPC_RXTX_BUFF_SIZE 64
500#define RXRPC_RXTX_BUFF_MASK (RXRPC_RXTX_BUFF_SIZE - 1) 500#define RXRPC_RXTX_BUFF_MASK (RXRPC_RXTX_BUFF_SIZE - 1)
501#define RXRPC_INIT_RX_WINDOW_SIZE 32
501 struct sk_buff **rxtx_buffer; 502 struct sk_buff **rxtx_buffer;
502 u8 *rxtx_annotations; 503 u8 *rxtx_annotations;
503#define RXRPC_TX_ANNO_ACK 0 504#define RXRPC_TX_ANNO_ACK 0
@@ -518,7 +519,7 @@ struct rxrpc_call {
518 rxrpc_seq_t rx_expect_next; /* Expected next packet sequence number */ 519 rxrpc_seq_t rx_expect_next; /* Expected next packet sequence number */
519 u8 rx_winsize; /* Size of Rx window */ 520 u8 rx_winsize; /* Size of Rx window */
520 u8 tx_winsize; /* Maximum size of Tx window */ 521 u8 tx_winsize; /* Maximum size of Tx window */
521 u8 nr_jumbo_dup; /* Number of jumbo duplicates */ 522 u8 nr_jumbo_bad; /* Number of jumbo dups/exceeds-windows */
522 523
523 /* receive-phase ACK management */ 524 /* receive-phase ACK management */
524 u8 ackr_reason; /* reason to ACK */ 525 u8 ackr_reason; /* reason to ACK */
diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
index 9aa1c4b53563..22f9b0d1a138 100644
--- a/net/rxrpc/call_object.c
+++ b/net/rxrpc/call_object.c
@@ -152,7 +152,7 @@ struct rxrpc_call *rxrpc_alloc_call(gfp_t gfp)
152 memset(&call->sock_node, 0xed, sizeof(call->sock_node)); 152 memset(&call->sock_node, 0xed, sizeof(call->sock_node));
153 153
154 /* Leave space in the ring to handle a maxed-out jumbo packet */ 154 /* Leave space in the ring to handle a maxed-out jumbo packet */
155 call->rx_winsize = RXRPC_RXTX_BUFF_SIZE - 1 - 46; 155 call->rx_winsize = rxrpc_rx_window_size;
156 call->tx_winsize = 16; 156 call->tx_winsize = 16;
157 call->rx_expect_next = 1; 157 call->rx_expect_next = 1;
158 return call; 158 return call;
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index 8e529afcd6c1..75af0bd316c7 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -164,7 +164,7 @@ protocol_error:
164 * (that information is encoded in the ACK packet). 164 * (that information is encoded in the ACK packet).
165 */ 165 */
166static void rxrpc_input_dup_data(struct rxrpc_call *call, rxrpc_seq_t seq, 166static void rxrpc_input_dup_data(struct rxrpc_call *call, rxrpc_seq_t seq,
167 u8 annotation, bool *_jumbo_dup) 167 u8 annotation, bool *_jumbo_bad)
168{ 168{
169 /* Discard normal packets that are duplicates. */ 169 /* Discard normal packets that are duplicates. */
170 if (annotation == 0) 170 if (annotation == 0)
@@ -174,9 +174,9 @@ static void rxrpc_input_dup_data(struct rxrpc_call *call, rxrpc_seq_t seq,
174 * more partially duplicate jumbo packets, we refuse to take any more 174 * more partially duplicate jumbo packets, we refuse to take any more
175 * jumbos for this call. 175 * jumbos for this call.
176 */ 176 */
177 if (!*_jumbo_dup) { 177 if (!*_jumbo_bad) {
178 call->nr_jumbo_dup++; 178 call->nr_jumbo_bad++;
179 *_jumbo_dup = true; 179 *_jumbo_bad = true;
180 } 180 }
181} 181}
182 182
@@ -191,7 +191,7 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb,
191 unsigned int ix; 191 unsigned int ix;
192 rxrpc_serial_t serial = sp->hdr.serial, ack_serial = 0; 192 rxrpc_serial_t serial = sp->hdr.serial, ack_serial = 0;
193 rxrpc_seq_t seq = sp->hdr.seq, hard_ack; 193 rxrpc_seq_t seq = sp->hdr.seq, hard_ack;
194 bool immediate_ack = false, jumbo_dup = false, queued; 194 bool immediate_ack = false, jumbo_bad = false, queued;
195 u16 len; 195 u16 len;
196 u8 ack = 0, flags, annotation = 0; 196 u8 ack = 0, flags, annotation = 0;
197 197
@@ -222,7 +222,7 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb,
222 222
223 flags = sp->hdr.flags; 223 flags = sp->hdr.flags;
224 if (flags & RXRPC_JUMBO_PACKET) { 224 if (flags & RXRPC_JUMBO_PACKET) {
225 if (call->nr_jumbo_dup > 3) { 225 if (call->nr_jumbo_bad > 3) {
226 ack = RXRPC_ACK_NOSPACE; 226 ack = RXRPC_ACK_NOSPACE;
227 ack_serial = serial; 227 ack_serial = serial;
228 goto ack; 228 goto ack;
@@ -259,7 +259,7 @@ next_subpacket:
259 } 259 }
260 260
261 if (call->rxtx_buffer[ix]) { 261 if (call->rxtx_buffer[ix]) {
262 rxrpc_input_dup_data(call, seq, annotation, &jumbo_dup); 262 rxrpc_input_dup_data(call, seq, annotation, &jumbo_bad);
263 if (ack != RXRPC_ACK_DUPLICATE) { 263 if (ack != RXRPC_ACK_DUPLICATE) {
264 ack = RXRPC_ACK_DUPLICATE; 264 ack = RXRPC_ACK_DUPLICATE;
265 ack_serial = serial; 265 ack_serial = serial;
@@ -304,6 +304,15 @@ skip:
304 annotation++; 304 annotation++;
305 if (flags & RXRPC_JUMBO_PACKET) 305 if (flags & RXRPC_JUMBO_PACKET)
306 annotation |= RXRPC_RX_ANNO_JLAST; 306 annotation |= RXRPC_RX_ANNO_JLAST;
307 if (after(seq, hard_ack + call->rx_winsize)) {
308 ack = RXRPC_ACK_EXCEEDS_WINDOW;
309 ack_serial = serial;
310 if (!jumbo_bad) {
311 call->nr_jumbo_bad++;
312 jumbo_bad = true;
313 }
314 goto ack;
315 }
307 316
308 _proto("Rx DATA Jumbo %%%u", serial); 317 _proto("Rx DATA Jumbo %%%u", serial);
309 goto next_subpacket; 318 goto next_subpacket;
diff --git a/net/rxrpc/misc.c b/net/rxrpc/misc.c
index fd096f742e4b..8b910780f1ac 100644
--- a/net/rxrpc/misc.c
+++ b/net/rxrpc/misc.c
@@ -50,7 +50,10 @@ unsigned int rxrpc_idle_ack_delay = 0.5 * HZ;
50 * limit is hit, we should generate an EXCEEDS_WINDOW ACK and discard further 50 * limit is hit, we should generate an EXCEEDS_WINDOW ACK and discard further
51 * packets. 51 * packets.
52 */ 52 */
53unsigned int rxrpc_rx_window_size = RXRPC_RXTX_BUFF_SIZE - 46; 53unsigned int rxrpc_rx_window_size = RXRPC_INIT_RX_WINDOW_SIZE;
54#if (RXRPC_RXTX_BUFF_SIZE - 1) < RXRPC_INIT_RX_WINDOW_SIZE
55#error Need to reduce RXRPC_INIT_RX_WINDOW_SIZE
56#endif
54 57
55/* 58/*
56 * Maximum Rx MTU size. This indicates to the sender the size of jumbo packet 59 * Maximum Rx MTU size. This indicates to the sender the size of jumbo packet
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index 719a4c23f09d..90c7722d5779 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -71,10 +71,10 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_call *call,
71 71
72 mtu = call->conn->params.peer->if_mtu; 72 mtu = call->conn->params.peer->if_mtu;
73 mtu -= call->conn->params.peer->hdrsize; 73 mtu -= call->conn->params.peer->hdrsize;
74 jmax = (call->nr_jumbo_dup > 3) ? 1 : rxrpc_rx_jumbo_max; 74 jmax = (call->nr_jumbo_bad > 3) ? 1 : rxrpc_rx_jumbo_max;
75 pkt->ackinfo.rxMTU = htonl(rxrpc_rx_mtu); 75 pkt->ackinfo.rxMTU = htonl(rxrpc_rx_mtu);
76 pkt->ackinfo.maxMTU = htonl(mtu); 76 pkt->ackinfo.maxMTU = htonl(mtu);
77 pkt->ackinfo.rwind = htonl(rxrpc_rx_window_size); 77 pkt->ackinfo.rwind = htonl(call->rx_winsize);
78 pkt->ackinfo.jumbo_max = htonl(jmax); 78 pkt->ackinfo.jumbo_max = htonl(jmax);
79 79
80 *ackp++ = 0; 80 *ackp++ = 0;
diff --git a/net/rxrpc/sysctl.c b/net/rxrpc/sysctl.c
index b7ca8cf13c84..a03c61c672f5 100644
--- a/net/rxrpc/sysctl.c
+++ b/net/rxrpc/sysctl.c
@@ -20,7 +20,7 @@ static const unsigned int one = 1;
20static const unsigned int four = 4; 20static const unsigned int four = 4;
21static const unsigned int thirtytwo = 32; 21static const unsigned int thirtytwo = 32;
22static const unsigned int n_65535 = 65535; 22static const unsigned int n_65535 = 65535;
23static const unsigned int n_max_acks = RXRPC_MAXACKS; 23static const unsigned int n_max_acks = RXRPC_RXTX_BUFF_SIZE - 1;
24 24
25/* 25/*
26 * RxRPC operating parameters. 26 * RxRPC operating parameters.