aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/afs/rotate.c4
-rw-r--r--include/trace/events/rxrpc.h32
-rw-r--r--net/rxrpc/ar-internal.h2
-rw-r--r--net/rxrpc/call_event.c8
-rw-r--r--net/rxrpc/input.c10
5 files changed, 53 insertions, 3 deletions
diff --git a/fs/afs/rotate.c b/fs/afs/rotate.c
index e065bc0768e6..1faef56b12bd 100644
--- a/fs/afs/rotate.c
+++ b/fs/afs/rotate.c
@@ -310,6 +310,10 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
310 case -ETIME: 310 case -ETIME:
311 _debug("no conn"); 311 _debug("no conn");
312 goto iterate_address; 312 goto iterate_address;
313
314 case -ECONNRESET:
315 _debug("call reset");
316 goto failed;
313 } 317 }
314 318
315restart_from_beginning: 319restart_from_beginning:
diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h
index 077e664ac9a2..4fff00e9da8a 100644
--- a/include/trace/events/rxrpc.h
+++ b/include/trace/events/rxrpc.h
@@ -1459,6 +1459,38 @@ TRACE_EVENT(rxrpc_tx_fail,
1459 __print_symbolic(__entry->what, rxrpc_tx_fail_traces)) 1459 __print_symbolic(__entry->what, rxrpc_tx_fail_traces))
1460 ); 1460 );
1461 1461
1462TRACE_EVENT(rxrpc_call_reset,
1463 TP_PROTO(struct rxrpc_call *call),
1464
1465 TP_ARGS(call),
1466
1467 TP_STRUCT__entry(
1468 __field(unsigned int, debug_id )
1469 __field(u32, cid )
1470 __field(u32, call_id )
1471 __field(rxrpc_serial_t, call_serial )
1472 __field(rxrpc_serial_t, conn_serial )
1473 __field(rxrpc_seq_t, tx_seq )
1474 __field(rxrpc_seq_t, rx_seq )
1475 ),
1476
1477 TP_fast_assign(
1478 __entry->debug_id = call->debug_id;
1479 __entry->cid = call->cid;
1480 __entry->call_id = call->call_id;
1481 __entry->call_serial = call->rx_serial;
1482 __entry->conn_serial = call->conn->hi_serial;
1483 __entry->tx_seq = call->tx_hard_ack;
1484 __entry->rx_seq = call->ackr_seen;
1485 ),
1486
1487 TP_printk("c=%08x %08x:%08x r=%08x/%08x tx=%08x rx=%08x",
1488 __entry->debug_id,
1489 __entry->cid, __entry->call_id,
1490 __entry->call_serial, __entry->conn_serial,
1491 __entry->tx_seq, __entry->rx_seq)
1492 );
1493
1462#endif /* _TRACE_RXRPC_H */ 1494#endif /* _TRACE_RXRPC_H */
1463 1495
1464/* This part must be outside protection */ 1496/* This part must be outside protection */
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 19975d2ca9a2..b2393113a251 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -477,6 +477,7 @@ enum rxrpc_call_flag {
477 RXRPC_CALL_PINGING, /* Ping in process */ 477 RXRPC_CALL_PINGING, /* Ping in process */
478 RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */ 478 RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */
479 RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */ 479 RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */
480 RXRPC_CALL_RX_HEARD, /* The peer responded at least once to this call */
480}; 481};
481 482
482/* 483/*
@@ -624,6 +625,7 @@ struct rxrpc_call {
624 */ 625 */
625 rxrpc_seq_t rx_top; /* Highest Rx slot allocated. */ 626 rxrpc_seq_t rx_top; /* Highest Rx slot allocated. */
626 rxrpc_seq_t rx_expect_next; /* Expected next packet sequence number */ 627 rxrpc_seq_t rx_expect_next; /* Expected next packet sequence number */
628 rxrpc_serial_t rx_serial; /* Highest serial received for this call */
627 u8 rx_winsize; /* Size of Rx window */ 629 u8 rx_winsize; /* Size of Rx window */
628 u8 tx_winsize; /* Maximum size of Tx window */ 630 u8 tx_winsize; /* Maximum size of Tx window */
629 bool tx_phase; /* T if transmission phase, F if receive phase */ 631 bool tx_phase; /* T if transmission phase, F if receive phase */
diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c
index 6e0d788b4dc4..20210418904b 100644
--- a/net/rxrpc/call_event.c
+++ b/net/rxrpc/call_event.c
@@ -392,7 +392,13 @@ recheck_state:
392 392
393 /* Process events */ 393 /* Process events */
394 if (test_and_clear_bit(RXRPC_CALL_EV_EXPIRED, &call->events)) { 394 if (test_and_clear_bit(RXRPC_CALL_EV_EXPIRED, &call->events)) {
395 rxrpc_abort_call("EXP", call, 0, RX_USER_ABORT, -ETIME); 395 if (test_bit(RXRPC_CALL_RX_HEARD, &call->flags) &&
396 (int)call->conn->hi_serial - (int)call->rx_serial > 0) {
397 trace_rxrpc_call_reset(call);
398 rxrpc_abort_call("EXP", call, 0, RX_USER_ABORT, -ECONNRESET);
399 } else {
400 rxrpc_abort_call("EXP", call, 0, RX_USER_ABORT, -ETIME);
401 }
396 set_bit(RXRPC_CALL_EV_ABORT, &call->events); 402 set_bit(RXRPC_CALL_EV_ABORT, &call->events);
397 goto recheck_state; 403 goto recheck_state;
398 } 404 }
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index b5fd6381313d..608d078a4981 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -1278,8 +1278,14 @@ void rxrpc_data_ready(struct sock *udp_sk)
1278 call = NULL; 1278 call = NULL;
1279 } 1279 }
1280 1280
1281 if (call && sp->hdr.serviceId != call->service_id) 1281 if (call) {
1282 call->service_id = sp->hdr.serviceId; 1282 if (sp->hdr.serviceId != call->service_id)
1283 call->service_id = sp->hdr.serviceId;
1284 if ((int)sp->hdr.serial - (int)call->rx_serial > 0)
1285 call->rx_serial = sp->hdr.serial;
1286 if (!test_bit(RXRPC_CALL_RX_HEARD, &call->flags))
1287 set_bit(RXRPC_CALL_RX_HEARD, &call->flags);
1288 }
1283 } else { 1289 } else {
1284 skew = 0; 1290 skew = 0;
1285 call = NULL; 1291 call = NULL;