mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
rxrpc: Defer the response to a PING ACK until we've parsed it
Defer the generation of a PING RESPONSE ACK in response to a PING ACK until we've parsed the PING ACK so that we pick up any changes to the packet queue so that we can update ackinfo. This is also applied to an ACK generated in response to an ACK with the REQUEST_ACK flag set. Note that whilst the problem was added in commit248f219cb8
, it didn't really matter at that point because the ACK was proposed in softirq mode and generated asynchronously later in process context, taking the latest values at the time. But this fix is only needed since the move to parse incoming packets in an I/O thread rather than in softirq and generate the ACK at point of proposal (b0346843b1
). Fixes:248f219cb8
("rxrpc: Rewrite the data and ack handling code") Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: "David S. Miller" <davem@davemloft.net> cc: Eric Dumazet <edumazet@google.com> cc: Jakub Kicinski <kuba@kernel.org> cc: Paolo Abeni <pabeni@redhat.com> cc: linux-afs@lists.infradead.org cc: netdev@vger.kernel.org Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3798680f2f
commit
1a01319fee
@ -814,14 +814,6 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
|
||||
}
|
||||
}
|
||||
|
||||
if (ack.reason == RXRPC_ACK_PING) {
|
||||
rxrpc_send_ACK(call, RXRPC_ACK_PING_RESPONSE, ack_serial,
|
||||
rxrpc_propose_ack_respond_to_ping);
|
||||
} else if (sp->hdr.flags & RXRPC_REQUEST_ACK) {
|
||||
rxrpc_send_ACK(call, RXRPC_ACK_REQUESTED, ack_serial,
|
||||
rxrpc_propose_ack_respond_to_ack);
|
||||
}
|
||||
|
||||
/* If we get an EXCEEDS_WINDOW ACK from the server, it probably
|
||||
* indicates that the client address changed due to NAT. The server
|
||||
* lost the call because it switched to a different peer.
|
||||
@ -832,7 +824,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
|
||||
rxrpc_is_client_call(call)) {
|
||||
rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED,
|
||||
0, -ENETRESET);
|
||||
return;
|
||||
goto send_response;
|
||||
}
|
||||
|
||||
/* If we get an OUT_OF_SEQUENCE ACK from the server, that can also
|
||||
@ -846,7 +838,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
|
||||
rxrpc_is_client_call(call)) {
|
||||
rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED,
|
||||
0, -ENETRESET);
|
||||
return;
|
||||
goto send_response;
|
||||
}
|
||||
|
||||
/* Discard any out-of-order or duplicate ACKs (outside lock). */
|
||||
@ -854,7 +846,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
|
||||
trace_rxrpc_rx_discard_ack(call->debug_id, ack_serial,
|
||||
first_soft_ack, call->acks_first_seq,
|
||||
prev_pkt, call->acks_prev_seq);
|
||||
return;
|
||||
goto send_response;
|
||||
}
|
||||
|
||||
info.rxMTU = 0;
|
||||
@ -894,7 +886,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
|
||||
case RXRPC_CALL_SERVER_AWAIT_ACK:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
goto send_response;
|
||||
}
|
||||
|
||||
if (before(hard_ack, call->acks_hard_ack) ||
|
||||
@ -906,7 +898,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
|
||||
if (after(hard_ack, call->acks_hard_ack)) {
|
||||
if (rxrpc_rotate_tx_window(call, hard_ack, &summary)) {
|
||||
rxrpc_end_tx_phase(call, false, rxrpc_eproto_unexpected_ack);
|
||||
return;
|
||||
goto send_response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -924,6 +916,14 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
|
||||
rxrpc_propose_ack_ping_for_lost_reply);
|
||||
|
||||
rxrpc_congestion_management(call, skb, &summary, acked_serial);
|
||||
|
||||
send_response:
|
||||
if (ack.reason == RXRPC_ACK_PING)
|
||||
rxrpc_send_ACK(call, RXRPC_ACK_PING_RESPONSE, ack_serial,
|
||||
rxrpc_propose_ack_respond_to_ping);
|
||||
else if (sp->hdr.flags & RXRPC_REQUEST_ACK)
|
||||
rxrpc_send_ACK(call, RXRPC_ACK_REQUESTED, ack_serial,
|
||||
rxrpc_propose_ack_respond_to_ack);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user