0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/net.h>
0012 #include "ar-internal.h"
0013
0014 #define RXRPC_RTO_MAX ((unsigned)(120 * HZ))
0015 #define RXRPC_TIMEOUT_INIT ((unsigned)(1*HZ))
0016 #define rxrpc_jiffies32 ((u32)jiffies)
0017
0018 static u32 rxrpc_rto_min_us(struct rxrpc_peer *peer)
0019 {
0020 return 200;
0021 }
0022
0023 static u32 __rxrpc_set_rto(const struct rxrpc_peer *peer)
0024 {
0025 return usecs_to_jiffies((peer->srtt_us >> 3) + peer->rttvar_us);
0026 }
0027
0028 static u32 rxrpc_bound_rto(u32 rto)
0029 {
0030 return min(rto, RXRPC_RTO_MAX);
0031 }
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 static void rxrpc_rtt_estimator(struct rxrpc_peer *peer, long sample_rtt_us)
0044 {
0045 long m = sample_rtt_us;
0046 u32 srtt = peer->srtt_us;
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 if (srtt != 0) {
0065 m -= (srtt >> 3);
0066 srtt += m;
0067 if (m < 0) {
0068 m = -m;
0069 m -= (peer->mdev_us >> 2);
0070
0071
0072
0073
0074
0075
0076
0077
0078 if (m > 0)
0079 m >>= 3;
0080 } else {
0081 m -= (peer->mdev_us >> 2);
0082 }
0083
0084 peer->mdev_us += m;
0085 if (peer->mdev_us > peer->mdev_max_us) {
0086 peer->mdev_max_us = peer->mdev_us;
0087 if (peer->mdev_max_us > peer->rttvar_us)
0088 peer->rttvar_us = peer->mdev_max_us;
0089 }
0090 } else {
0091
0092 srtt = m << 3;
0093 peer->mdev_us = m << 1;
0094 peer->rttvar_us = max(peer->mdev_us, rxrpc_rto_min_us(peer));
0095 peer->mdev_max_us = peer->rttvar_us;
0096 }
0097
0098 peer->srtt_us = max(1U, srtt);
0099 }
0100
0101
0102
0103
0104
0105 static void rxrpc_set_rto(struct rxrpc_peer *peer)
0106 {
0107 u32 rto;
0108
0109
0110
0111
0112
0113
0114
0115
0116 rto = __rxrpc_set_rto(peer);
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127 peer->rto_j = rxrpc_bound_rto(rto);
0128 }
0129
0130 static void rxrpc_ack_update_rtt(struct rxrpc_peer *peer, long rtt_us)
0131 {
0132 if (rtt_us < 0)
0133 return;
0134
0135
0136 rxrpc_rtt_estimator(peer, rtt_us);
0137 rxrpc_set_rto(peer);
0138
0139
0140 peer->backoff = 0;
0141 }
0142
0143
0144
0145
0146
0147 void rxrpc_peer_add_rtt(struct rxrpc_call *call, enum rxrpc_rtt_rx_trace why,
0148 int rtt_slot,
0149 rxrpc_serial_t send_serial, rxrpc_serial_t resp_serial,
0150 ktime_t send_time, ktime_t resp_time)
0151 {
0152 struct rxrpc_peer *peer = call->peer;
0153 s64 rtt_us;
0154
0155 rtt_us = ktime_to_us(ktime_sub(resp_time, send_time));
0156 if (rtt_us < 0)
0157 return;
0158
0159 spin_lock(&peer->rtt_input_lock);
0160 rxrpc_ack_update_rtt(peer, rtt_us);
0161 if (peer->rtt_count < 3)
0162 peer->rtt_count++;
0163 spin_unlock(&peer->rtt_input_lock);
0164
0165 trace_rxrpc_rtt_rx(call, why, rtt_slot, send_serial, resp_serial,
0166 peer->srtt_us >> 3, peer->rto_j);
0167 }
0168
0169
0170
0171
0172
0173 unsigned long rxrpc_get_rto_backoff(struct rxrpc_peer *peer, bool retrans)
0174 {
0175 u64 timo_j;
0176 u8 backoff = READ_ONCE(peer->backoff);
0177
0178 timo_j = peer->rto_j;
0179 timo_j <<= backoff;
0180 if (retrans && timo_j * 2 <= RXRPC_RTO_MAX)
0181 WRITE_ONCE(peer->backoff, backoff + 1);
0182
0183 if (timo_j < 1)
0184 timo_j = 1;
0185
0186 return timo_j;
0187 }
0188
0189 void rxrpc_peer_init_rtt(struct rxrpc_peer *peer)
0190 {
0191 peer->rto_j = RXRPC_TIMEOUT_INIT;
0192 peer->mdev_us = jiffies_to_usecs(RXRPC_TIMEOUT_INIT);
0193 peer->backoff = 0;
0194
0195 }