Skip to content

Commit

Permalink
tcp: make TCP_INFO more consistent
Browse files Browse the repository at this point in the history
tcp_get_info() has to lock the socket, so lets lock it
for an extended critical section, so that various fields
have consistent values.

This solves an annoying issue that some applications
reported when multiple counters are updated during one
particular rx/rx event, and TCP_INFO was called from
another cpu.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Yuchung Cheng <ycheng@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Jan 9, 2017
1 parent c22e5c1 commit b369e7f
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions net/ipv4/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2766,6 +2766,9 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
info->tcpi_sacked = sk->sk_max_ack_backlog;
return;
}

slow = lock_sock_fast(sk);

info->tcpi_ca_state = icsk->icsk_ca_state;
info->tcpi_retransmits = icsk->icsk_retransmits;
info->tcpi_probes = icsk->icsk_probes_out;
Expand Down Expand Up @@ -2816,15 +2819,11 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)

info->tcpi_total_retrans = tp->total_retrans;

slow = lock_sock_fast(sk);

info->tcpi_bytes_acked = tp->bytes_acked;
info->tcpi_bytes_received = tp->bytes_received;
info->tcpi_notsent_bytes = max_t(int, 0, tp->write_seq - tp->snd_nxt);
tcp_get_info_chrono_stats(tp, info);

unlock_sock_fast(sk, slow);

info->tcpi_segs_out = tp->segs_out;
info->tcpi_segs_in = tp->segs_in;

Expand All @@ -2840,6 +2839,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
do_div(rate64, intv);
info->tcpi_delivery_rate = rate64;
}
unlock_sock_fast(sk, slow);
}
EXPORT_SYMBOL_GPL(tcp_get_info);

Expand Down

0 comments on commit b369e7f

Please sign in to comment.