Skip to content

Commit ddc7834

Browse files
committed
rxrpc: Fix loss of final ack on shutdown
Fix the loss of transmission of a call's final ack when a socket gets shut down. This means that the server will retransmit the last data packet or send a ping ack and then get an ICMP indicating the port got closed. The server will then view this as a failure. Fixes: 3136ef4 ("rxrpc: Delay terminal ACK transmission on a client call") Signed-off-by: David Howells <dhowells@redhat.com>
1 parent f3af4ad commit ddc7834

3 files changed

Lines changed: 7 additions & 3 deletions

File tree

net/rxrpc/ar-internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,7 @@ void rxrpc_clean_up_local_conns(struct rxrpc_local *);
831831
* conn_event.c
832832
*/
833833
void rxrpc_process_connection(struct work_struct *);
834+
void rxrpc_process_delayed_final_acks(struct rxrpc_connection *, bool);
834835

835836
/*
836837
* conn_object.c

net/rxrpc/conn_client.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,9 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
906906

907907
_enter("C=%x", conn->debug_id);
908908

909+
if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK)
910+
rxrpc_process_delayed_final_acks(conn, true);
911+
909912
spin_lock(&bundle->channel_lock);
910913
bindex = conn->bundle_shift / RXRPC_MAXCALLS;
911914
if (bundle->conns[bindex] == conn) {

net/rxrpc/conn_event.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ static void rxrpc_secure_connection(struct rxrpc_connection *conn)
397397
/*
398398
* Process delayed final ACKs that we haven't subsumed into a subsequent call.
399399
*/
400-
static void rxrpc_process_delayed_final_acks(struct rxrpc_connection *conn)
400+
void rxrpc_process_delayed_final_acks(struct rxrpc_connection *conn, bool force)
401401
{
402402
unsigned long j = jiffies, next_j;
403403
unsigned int channel;
@@ -416,7 +416,7 @@ static void rxrpc_process_delayed_final_acks(struct rxrpc_connection *conn)
416416
smp_rmb(); /* vs rxrpc_disconnect_client_call */
417417
ack_at = READ_ONCE(chan->final_ack_at);
418418

419-
if (time_before(j, ack_at)) {
419+
if (time_before(j, ack_at) && !force) {
420420
if (time_before(ack_at, next_j)) {
421421
next_j = ack_at;
422422
set = true;
@@ -450,7 +450,7 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn)
450450

451451
/* Process delayed ACKs whose time has come. */
452452
if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK)
453-
rxrpc_process_delayed_final_acks(conn);
453+
rxrpc_process_delayed_final_acks(conn, false);
454454

455455
/* go through the conn-level event packets, releasing the ref on this
456456
* connection that each one has when we've finished with it */

0 commit comments

Comments
 (0)