mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
rxrpc: Add keepalive for a call
We need to transmit a packet every so often to act as a keepalive for the peer (which has a timeout from the last time it received a packet) and also to prevent any intervening firewalls from closing the route. Do this by resetting a timer every time we transmit a packet. If the timer ever expires, we transmit a PING ACK packet and thereby also elicit a PING RESPONSE ACK from the other side - which prevents our last-rx timeout from expiring. The timer is set to 1/6 of the last-rx timeout so that we can detect the other side going away if it misses 6 replies in a row. This is particularly necessary for servers where the processing of the service function may take a significant amount of time. Signed-off-by: David Howells <[email protected]>
This commit is contained in:
parent
bd1fdf8cfd
commit
415f44e432
4 changed files with 40 additions and 0 deletions
|
|
@ -519,6 +519,7 @@ struct rxrpc_call {
|
|||
unsigned long ack_lost_at; /* When ACK is figured as lost */
|
||||
unsigned long resend_at; /* When next resend needs to happen */
|
||||
unsigned long ping_at; /* When next to send a ping */
|
||||
unsigned long keepalive_at; /* When next to send a keepalive ping */
|
||||
unsigned long expect_rx_by; /* When we expect to get a packet by */
|
||||
unsigned long expect_req_by; /* When we expect to get a request DATA packet by */
|
||||
unsigned long expect_term_by; /* When we expect call termination by */
|
||||
|
|
|
|||
|
|
@ -366,6 +366,15 @@ recheck_state:
|
|||
set_bit(RXRPC_CALL_EV_ACK_LOST, &call->events);
|
||||
}
|
||||
|
||||
t = READ_ONCE(call->keepalive_at);
|
||||
if (time_after_eq(now, t)) {
|
||||
trace_rxrpc_timer(call, rxrpc_timer_exp_keepalive, now);
|
||||
cmpxchg(&call->keepalive_at, t, now + MAX_JIFFY_OFFSET);
|
||||
rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, true,
|
||||
rxrpc_propose_ack_ping_for_keepalive);
|
||||
set_bit(RXRPC_CALL_EV_PING, &call->events);
|
||||
}
|
||||
|
||||
t = READ_ONCE(call->ping_at);
|
||||
if (time_after_eq(now, t)) {
|
||||
trace_rxrpc_timer(call, rxrpc_timer_exp_ping, now);
|
||||
|
|
@ -423,6 +432,7 @@ recheck_state:
|
|||
set(call->ack_at);
|
||||
set(call->ack_lost_at);
|
||||
set(call->resend_at);
|
||||
set(call->keepalive_at);
|
||||
set(call->ping_at);
|
||||
|
||||
now = jiffies;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,24 @@ struct rxrpc_abort_buffer {
|
|||
__be32 abort_code;
|
||||
};
|
||||
|
||||
/*
|
||||
* Arrange for a keepalive ping a certain time after we last transmitted. This
|
||||
* lets the far side know we're still interested in this call and helps keep
|
||||
* the route through any intervening firewall open.
|
||||
*
|
||||
* Receiving a response to the ping will prevent the ->expect_rx_by timer from
|
||||
* expiring.
|
||||
*/
|
||||
static void rxrpc_set_keepalive(struct rxrpc_call *call)
|
||||
{
|
||||
unsigned long now = jiffies, keepalive_at = call->next_rx_timo / 6;
|
||||
|
||||
keepalive_at += now;
|
||||
WRITE_ONCE(call->keepalive_at, keepalive_at);
|
||||
rxrpc_reduce_call_timer(call, keepalive_at, now,
|
||||
rxrpc_timer_set_for_keepalive);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill out an ACK packet.
|
||||
*/
|
||||
|
|
@ -205,6 +223,8 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
|
|||
call->ackr_seen = top;
|
||||
spin_unlock_bh(&call->lock);
|
||||
}
|
||||
|
||||
rxrpc_set_keepalive(call);
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
@ -388,6 +408,9 @@ done:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
rxrpc_set_keepalive(call);
|
||||
|
||||
_leave(" = %d [%u]", ret, call->peer->maxdata);
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue