Skip to content

Commit

Permalink
tcp: fix TCP socket rehash stats mis-accounting
Browse files Browse the repository at this point in the history
commit 9c30ae8 upstream.

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 <ycheng@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Link: https://lore.kernel.org/r/20210119192619.1848270-1-ycheng@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
yuchungcheng authored and gregkh committed Jan 27, 2021
1 parent fee5a83 commit a6fc831
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 22 deletions.
17 changes: 12 additions & 5 deletions include/net/sock.h
Expand Up @@ -1903,10 +1903,13 @@ static inline void sk_set_txhash(struct sock *sk)
sk->sk_txhash = net_tx_rndhash();
}

static inline void sk_rethink_txhash(struct sock *sk)
static inline bool sk_rethink_txhash(struct sock *sk)
{
if (sk->sk_txhash)
if (sk->sk_txhash) {
sk_set_txhash(sk);
return true;
}
return false;
}

static inline struct dst_entry *
Expand All @@ -1929,12 +1932,10 @@ sk_dst_get(struct sock *sk)
return dst;
}

static inline void dst_negative_advice(struct sock *sk)
static inline void __dst_negative_advice(struct sock *sk)
{
struct dst_entry *ndst, *dst = __sk_dst_get(sk);

sk_rethink_txhash(sk);

if (dst && dst->ops->negative_advice) {
ndst = dst->ops->negative_advice(dst);

Expand All @@ -1946,6 +1947,12 @@ static inline void dst_negative_advice(struct sock *sk)
}
}

static inline void dst_negative_advice(struct sock *sk)
{
sk_rethink_txhash(sk);
__dst_negative_advice(sk);
}

static inline void
__sk_dst_set(struct sock *sk, struct dst_entry *dst)
{
Expand Down
5 changes: 2 additions & 3 deletions net/ipv4/tcp_input.c
Expand Up @@ -4379,10 +4379,9 @@ static void tcp_rcv_spurious_retrans(struct sock *sk, const struct sk_buff *skb)
* The receiver remembers and reflects via DSACKs. Leverage the
* DSACK state and change the txhash to re-route speculatively.
*/
if (TCP_SKB_CB(skb)->seq == tcp_sk(sk)->duplicate_sack[0].start_seq) {
sk_rethink_txhash(sk);
if (TCP_SKB_CB(skb)->seq == tcp_sk(sk)->duplicate_sack[0].start_seq &&
sk_rethink_txhash(sk))
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPDUPLICATEDATAREHASH);
}
}

static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb)
Expand Down
22 changes: 8 additions & 14 deletions net/ipv4/tcp_timer.c
Expand Up @@ -219,27 +219,16 @@ static int tcp_write_timeout(struct sock *sk)
int retry_until;

if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
if (icsk->icsk_retransmits) {
dst_negative_advice(sk);
} else {
sk_rethink_txhash(sk);
tp->timeout_rehash++;
__NET_INC_STATS(sock_net(sk),
LINUX_MIB_TCPTIMEOUTREHASH);
}
if (icsk->icsk_retransmits)
__dst_negative_advice(sk);
retry_until = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries;
expired = icsk->icsk_retransmits >= retry_until;
} else {
if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1, 0)) {
/* Black hole detection */
tcp_mtu_probing(icsk, sk);

dst_negative_advice(sk);
} else {
sk_rethink_txhash(sk);
tp->timeout_rehash++;
__NET_INC_STATS(sock_net(sk),
LINUX_MIB_TCPTIMEOUTREHASH);
__dst_negative_advice(sk);
}

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

if (sk_rethink_txhash(sk)) {
tp->timeout_rehash++;
__NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEOUTREHASH);
}

return 0;
}

Expand Down

0 comments on commit a6fc831

Please sign in to comment.