| From 1d4adfaf65746203861c72d9d78de349eb97d528 Mon Sep 17 00:00:00 2001 |
| From: David Howells <dhowells@redhat.com> |
| Date: Thu, 20 Aug 2020 15:13:00 +0100 |
| Subject: [PATCH] rxrpc: Make rxrpc_kernel_get_srtt() indicate validity |
| |
| commit 1d4adfaf65746203861c72d9d78de349eb97d528 upstream. |
| |
| Fix rxrpc_kernel_get_srtt() to indicate the validity of the returned |
| smoothed RTT. If we haven't had any valid samples yet, the SRTT isn't |
| useful. |
| |
| Fixes: c410bf01933e ("rxrpc: Fix the excessive initial retransmission timeout") |
| Signed-off-by: David Howells <dhowells@redhat.com> |
| |
| diff --git a/fs/afs/fs_probe.c b/fs/afs/fs_probe.c |
| index 5d9ef517cf81..e7e98ad63a91 100644 |
| --- a/fs/afs/fs_probe.c |
| +++ b/fs/afs/fs_probe.c |
| @@ -161,8 +161,8 @@ void afs_fileserver_probe_result(struct afs_call *call) |
| } |
| } |
| |
| - rtt_us = rxrpc_kernel_get_srtt(call->net->socket, call->rxcall); |
| - if (rtt_us < server->probe.rtt) { |
| + if (rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us) && |
| + rtt_us < server->probe.rtt) { |
| server->probe.rtt = rtt_us; |
| server->rtt = rtt_us; |
| alist->preferred = index; |
| diff --git a/fs/afs/vl_probe.c b/fs/afs/vl_probe.c |
| index e3aa013c2177..081b7e5b13f5 100644 |
| --- a/fs/afs/vl_probe.c |
| +++ b/fs/afs/vl_probe.c |
| @@ -92,8 +92,8 @@ void afs_vlserver_probe_result(struct afs_call *call) |
| } |
| } |
| |
| - rtt_us = rxrpc_kernel_get_srtt(call->net->socket, call->rxcall); |
| - if (rtt_us < server->probe.rtt) { |
| + if (rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us) && |
| + rtt_us < server->probe.rtt) { |
| server->probe.rtt = rtt_us; |
| alist->preferred = index; |
| have_result = true; |
| diff --git a/include/net/af_rxrpc.h b/include/net/af_rxrpc.h |
| index 91eacbdcf33d..f6abcc0bbd6e 100644 |
| --- a/include/net/af_rxrpc.h |
| +++ b/include/net/af_rxrpc.h |
| @@ -59,7 +59,7 @@ bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *, |
| void rxrpc_kernel_end_call(struct socket *, struct rxrpc_call *); |
| void rxrpc_kernel_get_peer(struct socket *, struct rxrpc_call *, |
| struct sockaddr_rxrpc *); |
| -u32 rxrpc_kernel_get_srtt(struct socket *, struct rxrpc_call *); |
| +bool rxrpc_kernel_get_srtt(struct socket *, struct rxrpc_call *, u32 *); |
| int rxrpc_kernel_charge_accept(struct socket *, rxrpc_notify_rx_t, |
| rxrpc_user_attach_call_t, unsigned long, gfp_t, |
| unsigned int); |
| diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c |
| index ca29976bb193..68396d052052 100644 |
| --- a/net/rxrpc/peer_object.c |
| +++ b/net/rxrpc/peer_object.c |
| @@ -502,11 +502,21 @@ EXPORT_SYMBOL(rxrpc_kernel_get_peer); |
| * rxrpc_kernel_get_srtt - Get a call's peer smoothed RTT |
| * @sock: The socket on which the call is in progress. |
| * @call: The call to query |
| + * @_srtt: Where to store the SRTT value. |
| * |
| - * Get the call's peer smoothed RTT. |
| + * Get the call's peer smoothed RTT in uS. |
| */ |
| -u32 rxrpc_kernel_get_srtt(struct socket *sock, struct rxrpc_call *call) |
| +bool rxrpc_kernel_get_srtt(struct socket *sock, struct rxrpc_call *call, |
| + u32 *_srtt) |
| { |
| - return call->peer->srtt_us >> 3; |
| + struct rxrpc_peer *peer = call->peer; |
| + |
| + if (peer->rtt_count == 0) { |
| + *_srtt = 1000000; /* 1S */ |
| + return false; |
| + } |
| + |
| + *_srtt = call->peer->srtt_us >> 3; |
| + return true; |
| } |
| EXPORT_SYMBOL(rxrpc_kernel_get_srtt); |
| -- |
| 2.27.0 |
| |