diff options
Diffstat (limited to 'net/rxrpc')
-rw-r--r-- | net/rxrpc/af_rxrpc.c | 17 | ||||
-rw-r--r-- | net/rxrpc/ar-internal.h | 1 | ||||
-rw-r--r-- | net/rxrpc/conn_event.c | 11 | ||||
-rw-r--r-- | net/rxrpc/input.c | 18 | ||||
-rw-r--r-- | net/rxrpc/peer_event.c | 5 | ||||
-rw-r--r-- | net/rxrpc/sendmsg.c | 21 |
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 | */ |
381 | u32 rxrpc_kernel_check_life(const struct socket *sock, | 384 | bool 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 | } |
386 | EXPORT_SYMBOL(rxrpc_kernel_check_life); | 391 | EXPORT_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 | */ |
155 | static void rxrpc_abort_calls(struct rxrpc_connection *conn, | 155 | static 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 | */ |
158 | static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, | 159 | static 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 | ||
251 | out: | 252 | out: |
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); |