Skip to content

Commit 9c30ae8

Browse files
yuchungchengkuba-moo
authored andcommitted
tcp: fix TCP socket rehash stats mis-accounting
The previous commit 32efcc0 ("tcp: export count for rehash attempts") would mis-account rehashing SNMP and socket stats: a. During handshake of an active open, only counts the first SYN timeout b. After handshake of passive and active open, stop updating after (roughly) TCP_RETRIES1 recurring RTOs c. After the socket aborts, over count timeout_rehash by 1 This patch fixes this by checking the rehash result from sk_rethink_txhash. Fixes: 32efcc0 ("tcp: export count for rehash attempts") Signed-off-by: Yuchung Cheng <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: Neal Cardwell <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 8e4052c commit 9c30ae8

File tree

3 files changed

+22
-22
lines changed

3 files changed

+22
-22
lines changed

include/net/sock.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,10 +1921,13 @@ static inline void sk_set_txhash(struct sock *sk)
19211921
sk->sk_txhash = net_tx_rndhash();
19221922
}
19231923

1924-
static inline void sk_rethink_txhash(struct sock *sk)
1924+
static inline bool sk_rethink_txhash(struct sock *sk)
19251925
{
1926-
if (sk->sk_txhash)
1926+
if (sk->sk_txhash) {
19271927
sk_set_txhash(sk);
1928+
return true;
1929+
}
1930+
return false;
19281931
}
19291932

19301933
static inline struct dst_entry *
@@ -1947,12 +1950,10 @@ sk_dst_get(struct sock *sk)
19471950
return dst;
19481951
}
19491952

1950-
static inline void dst_negative_advice(struct sock *sk)
1953+
static inline void __dst_negative_advice(struct sock *sk)
19511954
{
19521955
struct dst_entry *ndst, *dst = __sk_dst_get(sk);
19531956

1954-
sk_rethink_txhash(sk);
1955-
19561957
if (dst && dst->ops->negative_advice) {
19571958
ndst = dst->ops->negative_advice(dst);
19581959

@@ -1964,6 +1965,12 @@ static inline void dst_negative_advice(struct sock *sk)
19641965
}
19651966
}
19661967

1968+
static inline void dst_negative_advice(struct sock *sk)
1969+
{
1970+
sk_rethink_txhash(sk);
1971+
__dst_negative_advice(sk);
1972+
}
1973+
19671974
static inline void
19681975
__sk_dst_set(struct sock *sk, struct dst_entry *dst)
19691976
{

net/ipv4/tcp_input.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4397,10 +4397,9 @@ static void tcp_rcv_spurious_retrans(struct sock *sk, const struct sk_buff *skb)
43974397
* The receiver remembers and reflects via DSACKs. Leverage the
43984398
* DSACK state and change the txhash to re-route speculatively.
43994399
*/
4400-
if (TCP_SKB_CB(skb)->seq == tcp_sk(sk)->duplicate_sack[0].start_seq) {
4401-
sk_rethink_txhash(sk);
4400+
if (TCP_SKB_CB(skb)->seq == tcp_sk(sk)->duplicate_sack[0].start_seq &&
4401+
sk_rethink_txhash(sk))
44024402
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPDUPLICATEDATAREHASH);
4403-
}
44044403
}
44054404

44064405
static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb)

net/ipv4/tcp_timer.c

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -219,27 +219,16 @@ static int tcp_write_timeout(struct sock *sk)
219219
int retry_until;
220220

221221
if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
222-
if (icsk->icsk_retransmits) {
223-
dst_negative_advice(sk);
224-
} else {
225-
sk_rethink_txhash(sk);
226-
tp->timeout_rehash++;
227-
__NET_INC_STATS(sock_net(sk),
228-
LINUX_MIB_TCPTIMEOUTREHASH);
229-
}
222+
if (icsk->icsk_retransmits)
223+
__dst_negative_advice(sk);
230224
retry_until = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries;
231225
expired = icsk->icsk_retransmits >= retry_until;
232226
} else {
233227
if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1, 0)) {
234228
/* Black hole detection */
235229
tcp_mtu_probing(icsk, sk);
236230

237-
dst_negative_advice(sk);
238-
} else {
239-
sk_rethink_txhash(sk);
240-
tp->timeout_rehash++;
241-
__NET_INC_STATS(sock_net(sk),
242-
LINUX_MIB_TCPTIMEOUTREHASH);
231+
__dst_negative_advice(sk);
243232
}
244233

245234
retry_until = net->ipv4.sysctl_tcp_retries2;
@@ -270,6 +259,11 @@ static int tcp_write_timeout(struct sock *sk)
270259
return 1;
271260
}
272261

262+
if (sk_rethink_txhash(sk)) {
263+
tp->timeout_rehash++;
264+
__NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEOUTREHASH);
265+
}
266+
273267
return 0;
274268
}
275269

0 commit comments

Comments
 (0)