summaryrefslogtreecommitdiffstats
path: root/net/rxrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/rxrpc')
-rw-r--r--net/rxrpc/af_rxrpc.c17
-rw-r--r--net/rxrpc/ar-internal.h1
-rw-r--r--net/rxrpc/conn_event.c11
-rw-r--r--net/rxrpc/input.c18
-rw-r--r--net/rxrpc/peer_event.c5
-rw-r--r--net/rxrpc/sendmsg.c21
6 files changed, 48 insertions, 25 deletions
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index 96f2952bbdfd..ae8c5d7f3bf1 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -135,7 +135,7 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
135 struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr; 135 struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr;
136 struct rxrpc_local *local; 136 struct rxrpc_local *local;
137 struct rxrpc_sock *rx = rxrpc_sk(sock->sk); 137 struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
138 u16 service_id = srx->srx_service; 138 u16 service_id;
139 int ret; 139 int ret;
140 140
141 _enter("%p,%p,%d", rx, saddr, len); 141 _enter("%p,%p,%d", rx, saddr, len);
@@ -143,6 +143,7 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
143 ret = rxrpc_validate_address(rx, srx, len); 143 ret = rxrpc_validate_address(rx, srx, len);
144 if (ret < 0) 144 if (ret < 0)
145 goto error; 145 goto error;
146 service_id = srx->srx_service;
146 147
147 lock_sock(&rx->sk); 148 lock_sock(&rx->sk);
148 149
@@ -370,18 +371,22 @@ EXPORT_SYMBOL(rxrpc_kernel_end_call);
370 * rxrpc_kernel_check_life - Check to see whether a call is still alive 371 * rxrpc_kernel_check_life - Check to see whether a call is still alive
371 * @sock: The socket the call is on 372 * @sock: The socket the call is on
372 * @call: The call to check 373 * @call: The call to check
374 * @_life: Where to store the life value
373 * 375 *
374 * Allow a kernel service to find out whether a call is still alive - ie. we're 376 * Allow a kernel service to find out whether a call is still alive - ie. we're
375 * getting ACKs from the server. Returns a number representing the life state 377 * getting ACKs from the server. Passes back in *_life a number representing
376 * which can be compared to that returned by a previous call. 378 * the life state which can be compared to that returned by a previous call and
379 * return true if the call is still alive.
377 * 380 *
378 * If the life state stalls, rxrpc_kernel_probe_life() should be called and 381 * If the life state stalls, rxrpc_kernel_probe_life() should be called and
379 * then 2RTT waited. 382 * then 2RTT waited.
380 */ 383 */
381u32 rxrpc_kernel_check_life(const struct socket *sock, 384bool rxrpc_kernel_check_life(const struct socket *sock,
382 const struct rxrpc_call *call) 385 const struct rxrpc_call *call,
386 u32 *_life)
383{ 387{
384 return call->acks_latest; 388 *_life = call->acks_latest;
389 return call->state != RXRPC_CALL_COMPLETE;
385} 390}
386EXPORT_SYMBOL(rxrpc_kernel_check_life); 391EXPORT_SYMBOL(rxrpc_kernel_check_life);
387 392
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 4b1a534d290a..062ca9dc29b8 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -654,6 +654,7 @@ struct rxrpc_call {
654 u8 ackr_reason; /* reason to ACK */ 654 u8 ackr_reason; /* reason to ACK */
655 u16 ackr_skew; /* skew on packet being ACK'd */ 655 u16 ackr_skew; /* skew on packet being ACK'd */
656 rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */ 656 rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */
657 rxrpc_serial_t ackr_first_seq; /* first sequence number received */
657 rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */ 658 rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */
658 rxrpc_seq_t ackr_consumed; /* Highest packet shown consumed */ 659 rxrpc_seq_t ackr_consumed; /* Highest packet shown consumed */
659 rxrpc_seq_t ackr_seen; /* Highest packet shown seen */ 660 rxrpc_seq_t ackr_seen; /* Highest packet shown seen */
diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c
index b6fca8ebb117..8d31fb4c51e1 100644
--- a/net/rxrpc/conn_event.c
+++ b/net/rxrpc/conn_event.c
@@ -153,7 +153,8 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
153 * pass a connection-level abort onto all calls on that connection 153 * pass a connection-level abort onto all calls on that connection
154 */ 154 */
155static void rxrpc_abort_calls(struct rxrpc_connection *conn, 155static void rxrpc_abort_calls(struct rxrpc_connection *conn,
156 enum rxrpc_call_completion compl) 156 enum rxrpc_call_completion compl,
157 rxrpc_serial_t serial)
157{ 158{
158 struct rxrpc_call *call; 159 struct rxrpc_call *call;
159 int i; 160 int i;
@@ -173,6 +174,9 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn,
173 call->call_id, 0, 174 call->call_id, 0,
174 conn->abort_code, 175 conn->abort_code,
175 conn->error); 176 conn->error);
177 else
178 trace_rxrpc_rx_abort(call, serial,
179 conn->abort_code);
176 if (rxrpc_set_call_completion(call, compl, 180 if (rxrpc_set_call_completion(call, compl,
177 conn->abort_code, 181 conn->abort_code,
178 conn->error)) 182 conn->error))
@@ -213,8 +217,6 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
213 conn->state = RXRPC_CONN_LOCALLY_ABORTED; 217 conn->state = RXRPC_CONN_LOCALLY_ABORTED;
214 spin_unlock_bh(&conn->state_lock); 218 spin_unlock_bh(&conn->state_lock);
215 219
216 rxrpc_abort_calls(conn, RXRPC_CALL_LOCALLY_ABORTED);
217
218 msg.msg_name = &conn->params.peer->srx.transport; 220 msg.msg_name = &conn->params.peer->srx.transport;
219 msg.msg_namelen = conn->params.peer->srx.transport_len; 221 msg.msg_namelen = conn->params.peer->srx.transport_len;
220 msg.msg_control = NULL; 222 msg.msg_control = NULL;
@@ -242,6 +244,7 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
242 len = iov[0].iov_len + iov[1].iov_len; 244 len = iov[0].iov_len + iov[1].iov_len;
243 245
244 serial = atomic_inc_return(&conn->serial); 246 serial = atomic_inc_return(&conn->serial);
247 rxrpc_abort_calls(conn, RXRPC_CALL_LOCALLY_ABORTED, serial);
245 whdr.serial = htonl(serial); 248 whdr.serial = htonl(serial);
246 _proto("Tx CONN ABORT %%%u { %d }", serial, conn->abort_code); 249 _proto("Tx CONN ABORT %%%u { %d }", serial, conn->abort_code);
247 250
@@ -321,7 +324,7 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
321 conn->error = -ECONNABORTED; 324 conn->error = -ECONNABORTED;
322 conn->abort_code = abort_code; 325 conn->abort_code = abort_code;
323 conn->state = RXRPC_CONN_REMOTELY_ABORTED; 326 conn->state = RXRPC_CONN_REMOTELY_ABORTED;
324 rxrpc_abort_calls(conn, RXRPC_CALL_REMOTELY_ABORTED); 327 rxrpc_abort_calls(conn, RXRPC_CALL_REMOTELY_ABORTED, sp->hdr.serial);
325 return -ECONNABORTED; 328 return -ECONNABORTED;
326 329
327 case RXRPC_PACKET_TYPE_CHALLENGE: 330 case RXRPC_PACKET_TYPE_CHALLENGE:
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index 9128aa0e40aa..4c6f9d0a00e7 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -837,7 +837,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
837 u8 acks[RXRPC_MAXACKS]; 837 u8 acks[RXRPC_MAXACKS];
838 } buf; 838 } buf;
839 rxrpc_serial_t acked_serial; 839 rxrpc_serial_t acked_serial;
840 rxrpc_seq_t first_soft_ack, hard_ack; 840 rxrpc_seq_t first_soft_ack, hard_ack, prev_pkt;
841 int nr_acks, offset, ioffset; 841 int nr_acks, offset, ioffset;
842 842
843 _enter(""); 843 _enter("");
@@ -851,13 +851,14 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
851 851
852 acked_serial = ntohl(buf.ack.serial); 852 acked_serial = ntohl(buf.ack.serial);
853 first_soft_ack = ntohl(buf.ack.firstPacket); 853 first_soft_ack = ntohl(buf.ack.firstPacket);
854 prev_pkt = ntohl(buf.ack.previousPacket);
854 hard_ack = first_soft_ack - 1; 855 hard_ack = first_soft_ack - 1;
855 nr_acks = buf.ack.nAcks; 856 nr_acks = buf.ack.nAcks;
856 summary.ack_reason = (buf.ack.reason < RXRPC_ACK__INVALID ? 857 summary.ack_reason = (buf.ack.reason < RXRPC_ACK__INVALID ?
857 buf.ack.reason : RXRPC_ACK__INVALID); 858 buf.ack.reason : RXRPC_ACK__INVALID);
858 859
859 trace_rxrpc_rx_ack(call, sp->hdr.serial, acked_serial, 860 trace_rxrpc_rx_ack(call, sp->hdr.serial, acked_serial,
860 first_soft_ack, ntohl(buf.ack.previousPacket), 861 first_soft_ack, prev_pkt,
861 summary.ack_reason, nr_acks); 862 summary.ack_reason, nr_acks);
862 863
863 if (buf.ack.reason == RXRPC_ACK_PING_RESPONSE) 864 if (buf.ack.reason == RXRPC_ACK_PING_RESPONSE)
@@ -878,8 +879,9 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
878 rxrpc_propose_ack_respond_to_ack); 879 rxrpc_propose_ack_respond_to_ack);
879 } 880 }
880 881
881 /* Discard any out-of-order or duplicate ACKs. */ 882 /* Discard any out-of-order or duplicate ACKs (outside lock). */
882 if (before_eq(sp->hdr.serial, call->acks_latest)) 883 if (before(first_soft_ack, call->ackr_first_seq) ||
884 before(prev_pkt, call->ackr_prev_seq))
883 return; 885 return;
884 886
885 buf.info.rxMTU = 0; 887 buf.info.rxMTU = 0;
@@ -890,12 +892,16 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
890 892
891 spin_lock(&call->input_lock); 893 spin_lock(&call->input_lock);
892 894
893 /* Discard any out-of-order or duplicate ACKs. */ 895 /* Discard any out-of-order or duplicate ACKs (inside lock). */
894 if (before_eq(sp->hdr.serial, call->acks_latest)) 896 if (before(first_soft_ack, call->ackr_first_seq) ||
897 before(prev_pkt, call->ackr_prev_seq))
895 goto out; 898 goto out;
896 call->acks_latest_ts = skb->tstamp; 899 call->acks_latest_ts = skb->tstamp;
897 call->acks_latest = sp->hdr.serial; 900 call->acks_latest = sp->hdr.serial;
898 901
902 call->ackr_first_seq = first_soft_ack;
903 call->ackr_prev_seq = prev_pkt;
904
899 /* Parse rwind and mtu sizes if provided. */ 905 /* Parse rwind and mtu sizes if provided. */
900 if (buf.info.rxMTU) 906 if (buf.info.rxMTU)
901 rxrpc_input_ackinfo(call, skb, &buf.info); 907 rxrpc_input_ackinfo(call, skb, &buf.info);
diff --git a/net/rxrpc/peer_event.c b/net/rxrpc/peer_event.c
index bc05af89fc38..6e84d878053c 100644
--- a/net/rxrpc/peer_event.c
+++ b/net/rxrpc/peer_event.c
@@ -157,6 +157,11 @@ void rxrpc_error_report(struct sock *sk)
157 157
158 _enter("%p{%d}", sk, local->debug_id); 158 _enter("%p{%d}", sk, local->debug_id);
159 159
160 /* Clear the outstanding error value on the socket so that it doesn't
161 * cause kernel_sendmsg() to return it later.
162 */
163 sock_error(sk);
164
160 skb = sock_dequeue_err_skb(sk); 165 skb = sock_dequeue_err_skb(sk);
161 if (!skb) { 166 if (!skb) {
162 _leave("UDP socket errqueue empty"); 167 _leave("UDP socket errqueue empty");
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
index 46c9312085b1..bec64deb7b0a 100644
--- a/net/rxrpc/sendmsg.c
+++ b/net/rxrpc/sendmsg.c
@@ -152,12 +152,13 @@ static void rxrpc_notify_end_tx(struct rxrpc_sock *rx, struct rxrpc_call *call,
152} 152}
153 153
154/* 154/*
155 * Queue a DATA packet for transmission, set the resend timeout and send the 155 * Queue a DATA packet for transmission, set the resend timeout and send
156 * packet immediately 156 * the packet immediately. Returns the error from rxrpc_send_data_packet()
157 * in case the caller wants to do something with it.
157 */ 158 */
158static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, 159static int rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
159 struct sk_buff *skb, bool last, 160 struct sk_buff *skb, bool last,
160 rxrpc_notify_end_tx_t notify_end_tx) 161 rxrpc_notify_end_tx_t notify_end_tx)
161{ 162{
162 struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 163 struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
163 unsigned long now; 164 unsigned long now;
@@ -250,7 +251,8 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
250 251
251out: 252out:
252 rxrpc_free_skb(skb, rxrpc_skb_tx_freed); 253 rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
253 _leave(""); 254 _leave(" = %d", ret);
255 return ret;
254} 256}
255 257
256/* 258/*
@@ -423,9 +425,10 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
423 if (ret < 0) 425 if (ret < 0)
424 goto out; 426 goto out;
425 427
426 rxrpc_queue_packet(rx, call, skb, 428 ret = rxrpc_queue_packet(rx, call, skb,
427 !msg_data_left(msg) && !more, 429 !msg_data_left(msg) && !more,
428 notify_end_tx); 430 notify_end_tx);
431 /* Should check for failure here */
429 skb = NULL; 432 skb = NULL;
430 } 433 }
431 } while (msg_data_left(msg) > 0); 434 } while (msg_data_left(msg) > 0);