Skip to content

Commit 9e550f0

Browse files
committed
Merge branch 'rxrpc-fixes'
David Howells says: ==================== rxrpc: Fixes Here is a collection of fixes for rxrpc: (1) rxrpc_error_report() needs to call sock_error() to clear the error code from the UDP transport socket, lest it be unexpectedly revisited on the next kernel_sendmsg() call. This has been causing all sorts of weird effects in AFS as the effects have typically been felt by the wrong RxRPC call. (2) Allow a kernel user of AF_RXRPC to easily detect if an rxrpc call has completed. (3) Allow errors incurred by attempting to transmit data through the UDP socket to get back up the stack to AFS. (4) Make AFS use (2) to abort the synchronous-mode call waiting loop if the rxrpc-level call completed. (5) Add a missing tracepoint case for tracing abort reception. (6) Fix detection and handling of out-of-order ACKs. ==================== Tested-by: Jonathan Billings <[email protected]> Signed-off-by: David S. Miller <[email protected]>
2 parents 1dc2b3d + 1a2391c commit 9e550f0

File tree

9 files changed

+75
-39
lines changed

9 files changed

+75
-39
lines changed

Documentation/networking/rxrpc.txt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,16 +1009,18 @@ The kernel interface functions are as follows:
10091009

10101010
(*) Check call still alive.
10111011

1012-
u32 rxrpc_kernel_check_life(struct socket *sock,
1013-
struct rxrpc_call *call);
1012+
bool rxrpc_kernel_check_life(struct socket *sock,
1013+
struct rxrpc_call *call,
1014+
u32 *_life);
10141015
void rxrpc_kernel_probe_life(struct socket *sock,
10151016
struct rxrpc_call *call);
10161017

1017-
The first function returns a number that is updated when ACKs are received
1018-
from the peer (notably including PING RESPONSE ACKs which we can elicit by
1019-
sending PING ACKs to see if the call still exists on the server). The
1020-
caller should compare the numbers of two calls to see if the call is still
1021-
alive after waiting for a suitable interval.
1018+
The first function passes back in *_life a number that is updated when
1019+
ACKs are received from the peer (notably including PING RESPONSE ACKs
1020+
which we can elicit by sending PING ACKs to see if the call still exists
1021+
on the server). The caller should compare the numbers of two calls to see
1022+
if the call is still alive after waiting for a suitable interval. It also
1023+
returns true as long as the call hasn't yet reached the completed state.
10221024

10231025
This allows the caller to work out if the server is still contactable and
10241026
if the call is still alive on the server while waiting for the server to

fs/afs/rxrpc.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ static long afs_wait_for_call_to_complete(struct afs_call *call,
610610
bool stalled = false;
611611
u64 rtt;
612612
u32 life, last_life;
613+
bool rxrpc_complete = false;
613614

614615
DECLARE_WAITQUEUE(myself, current);
615616

@@ -621,7 +622,7 @@ static long afs_wait_for_call_to_complete(struct afs_call *call,
621622
rtt2 = 2;
622623

623624
timeout = rtt2;
624-
last_life = rxrpc_kernel_check_life(call->net->socket, call->rxcall);
625+
rxrpc_kernel_check_life(call->net->socket, call->rxcall, &last_life);
625626

626627
add_wait_queue(&call->waitq, &myself);
627628
for (;;) {
@@ -639,7 +640,12 @@ static long afs_wait_for_call_to_complete(struct afs_call *call,
639640
if (afs_check_call_state(call, AFS_CALL_COMPLETE))
640641
break;
641642

642-
life = rxrpc_kernel_check_life(call->net->socket, call->rxcall);
643+
if (!rxrpc_kernel_check_life(call->net->socket, call->rxcall, &life)) {
644+
/* rxrpc terminated the call. */
645+
rxrpc_complete = true;
646+
break;
647+
}
648+
643649
if (timeout == 0 &&
644650
life == last_life && signal_pending(current)) {
645651
if (stalled)
@@ -663,12 +669,16 @@ static long afs_wait_for_call_to_complete(struct afs_call *call,
663669
remove_wait_queue(&call->waitq, &myself);
664670
__set_current_state(TASK_RUNNING);
665671

666-
/* Kill off the call if it's still live. */
667672
if (!afs_check_call_state(call, AFS_CALL_COMPLETE)) {
668-
_debug("call interrupted");
669-
if (rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
670-
RX_USER_ABORT, -EINTR, "KWI"))
671-
afs_set_call_complete(call, -EINTR, 0);
673+
if (rxrpc_complete) {
674+
afs_set_call_complete(call, call->error, call->abort_code);
675+
} else {
676+
/* Kill off the call if it's still live. */
677+
_debug("call interrupted");
678+
if (rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
679+
RX_USER_ABORT, -EINTR, "KWI"))
680+
afs_set_call_complete(call, -EINTR, 0);
681+
}
672682
}
673683

674684
spin_lock_bh(&call->state_lock);

include/net/af_rxrpc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,12 @@ int rxrpc_kernel_charge_accept(struct socket *, rxrpc_notify_rx_t,
6161
rxrpc_user_attach_call_t, unsigned long, gfp_t,
6262
unsigned int);
6363
void rxrpc_kernel_set_tx_length(struct socket *, struct rxrpc_call *, s64);
64-
u32 rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *);
64+
bool rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *,
65+
u32 *);
6566
void rxrpc_kernel_probe_life(struct socket *, struct rxrpc_call *);
6667
u32 rxrpc_kernel_get_epoch(struct socket *, struct rxrpc_call *);
6768
bool rxrpc_kernel_get_reply_time(struct socket *, struct rxrpc_call *,
6869
ktime_t *);
70+
bool rxrpc_kernel_call_is_complete(struct rxrpc_call *);
6971

7072
#endif /* _NET_RXRPC_H */

net/rxrpc/af_rxrpc.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -371,18 +371,22 @@ EXPORT_SYMBOL(rxrpc_kernel_end_call);
371371
* rxrpc_kernel_check_life - Check to see whether a call is still alive
372372
* @sock: The socket the call is on
373373
* @call: The call to check
374+
* @_life: Where to store the life value
374375
*
375376
* Allow a kernel service to find out whether a call is still alive - ie. we're
376-
* getting ACKs from the server. Returns a number representing the life state
377-
* which can be compared to that returned by a previous call.
377+
* getting ACKs from the server. Passes back in *_life a number representing
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.
378380
*
379381
* If the life state stalls, rxrpc_kernel_probe_life() should be called and
380382
* then 2RTT waited.
381383
*/
382-
u32 rxrpc_kernel_check_life(const struct socket *sock,
383-
const struct rxrpc_call *call)
384+
bool rxrpc_kernel_check_life(const struct socket *sock,
385+
const struct rxrpc_call *call,
386+
u32 *_life)
384387
{
385-
return call->acks_latest;
388+
*_life = call->acks_latest;
389+
return call->state != RXRPC_CALL_COMPLETE;
386390
}
387391
EXPORT_SYMBOL(rxrpc_kernel_check_life);
388392

net/rxrpc/ar-internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ struct rxrpc_call {
654654
u8 ackr_reason; /* reason to ACK */
655655
u16 ackr_skew; /* skew on packet being ACK'd */
656656
rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */
657+
rxrpc_serial_t ackr_first_seq; /* first sequence number received */
657658
rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */
658659
rxrpc_seq_t ackr_consumed; /* Highest packet shown consumed */
659660
rxrpc_seq_t ackr_seen; /* Highest packet shown seen */

net/rxrpc/conn_event.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
153153
* pass a connection-level abort onto all calls on that connection
154154
*/
155155
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)
157158
{
158159
struct rxrpc_call *call;
159160
int i;
@@ -173,6 +174,9 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn,
173174
call->call_id, 0,
174175
conn->abort_code,
175176
conn->error);
177+
else
178+
trace_rxrpc_rx_abort(call, serial,
179+
conn->abort_code);
176180
if (rxrpc_set_call_completion(call, compl,
177181
conn->abort_code,
178182
conn->error))
@@ -213,8 +217,6 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
213217
conn->state = RXRPC_CONN_LOCALLY_ABORTED;
214218
spin_unlock_bh(&conn->state_lock);
215219

216-
rxrpc_abort_calls(conn, RXRPC_CALL_LOCALLY_ABORTED);
217-
218220
msg.msg_name = &conn->params.peer->srx.transport;
219221
msg.msg_namelen = conn->params.peer->srx.transport_len;
220222
msg.msg_control = NULL;
@@ -242,6 +244,7 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
242244
len = iov[0].iov_len + iov[1].iov_len;
243245

244246
serial = atomic_inc_return(&conn->serial);
247+
rxrpc_abort_calls(conn, RXRPC_CALL_LOCALLY_ABORTED, serial);
245248
whdr.serial = htonl(serial);
246249
_proto("Tx CONN ABORT %%%u { %d }", serial, conn->abort_code);
247250

@@ -321,7 +324,7 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
321324
conn->error = -ECONNABORTED;
322325
conn->abort_code = abort_code;
323326
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);
325328
return -ECONNABORTED;
326329

327330
case RXRPC_PACKET_TYPE_CHALLENGE:

net/rxrpc/input.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
837837
u8 acks[RXRPC_MAXACKS];
838838
} buf;
839839
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;
841841
int nr_acks, offset, ioffset;
842842

843843
_enter("");
@@ -851,13 +851,14 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
851851

852852
acked_serial = ntohl(buf.ack.serial);
853853
first_soft_ack = ntohl(buf.ack.firstPacket);
854+
prev_pkt = ntohl(buf.ack.previousPacket);
854855
hard_ack = first_soft_ack - 1;
855856
nr_acks = buf.ack.nAcks;
856857
summary.ack_reason = (buf.ack.reason < RXRPC_ACK__INVALID ?
857858
buf.ack.reason : RXRPC_ACK__INVALID);
858859

859860
trace_rxrpc_rx_ack(call, sp->hdr.serial, acked_serial,
860-
first_soft_ack, ntohl(buf.ack.previousPacket),
861+
first_soft_ack, prev_pkt,
861862
summary.ack_reason, nr_acks);
862863

863864
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,
878879
rxrpc_propose_ack_respond_to_ack);
879880
}
880881

881-
/* Discard any out-of-order or duplicate ACKs. */
882-
if (before_eq(sp->hdr.serial, call->acks_latest))
882+
/* Discard any out-of-order or duplicate ACKs (outside lock). */
883+
if (before(first_soft_ack, call->ackr_first_seq) ||
884+
before(prev_pkt, call->ackr_prev_seq))
883885
return;
884886

885887
buf.info.rxMTU = 0;
@@ -890,12 +892,16 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
890892

891893
spin_lock(&call->input_lock);
892894

893-
/* Discard any out-of-order or duplicate ACKs. */
894-
if (before_eq(sp->hdr.serial, call->acks_latest))
895+
/* Discard any out-of-order or duplicate ACKs (inside lock). */
896+
if (before(first_soft_ack, call->ackr_first_seq) ||
897+
before(prev_pkt, call->ackr_prev_seq))
895898
goto out;
896899
call->acks_latest_ts = skb->tstamp;
897900
call->acks_latest = sp->hdr.serial;
898901

902+
call->ackr_first_seq = first_soft_ack;
903+
call->ackr_prev_seq = prev_pkt;
904+
899905
/* Parse rwind and mtu sizes if provided. */
900906
if (buf.info.rxMTU)
901907
rxrpc_input_ackinfo(call, skb, &buf.info);

net/rxrpc/peer_event.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ void rxrpc_error_report(struct sock *sk)
157157

158158
_enter("%p{%d}", sk, local->debug_id);
159159

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+
160165
skb = sock_dequeue_err_skb(sk);
161166
if (!skb) {
162167
_leave("UDP socket errqueue empty");

net/rxrpc/sendmsg.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,13 @@ static void rxrpc_notify_end_tx(struct rxrpc_sock *rx, struct rxrpc_call *call,
152152
}
153153

154154
/*
155-
* Queue a DATA packet for transmission, set the resend timeout and send the
156-
* packet immediately
155+
* Queue a DATA packet for transmission, set the resend timeout and send
156+
* the packet immediately. Returns the error from rxrpc_send_data_packet()
157+
* in case the caller wants to do something with it.
157158
*/
158-
static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
159-
struct sk_buff *skb, bool last,
160-
rxrpc_notify_end_tx_t notify_end_tx)
159+
static int rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
160+
struct sk_buff *skb, bool last,
161+
rxrpc_notify_end_tx_t notify_end_tx)
161162
{
162163
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
163164
unsigned long now;
@@ -250,7 +251,8 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
250251

251252
out:
252253
rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
253-
_leave("");
254+
_leave(" = %d", ret);
255+
return ret;
254256
}
255257

256258
/*
@@ -423,9 +425,10 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
423425
if (ret < 0)
424426
goto out;
425427

426-
rxrpc_queue_packet(rx, call, skb,
427-
!msg_data_left(msg) && !more,
428-
notify_end_tx);
428+
ret = rxrpc_queue_packet(rx, call, skb,
429+
!msg_data_left(msg) && !more,
430+
notify_end_tx);
431+
/* Should check for failure here */
429432
skb = NULL;
430433
}
431434
} while (msg_data_left(msg) > 0);

0 commit comments

Comments
 (0)