Skip to content

Commit b369e7f

Browse files
edumazetdavem330
authored andcommitted
tcp: make TCP_INFO more consistent
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 <[email protected]> Cc: Yuchung Cheng <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c22e5c1 commit b369e7f

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

net/ipv4/tcp.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2766,6 +2766,9 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
27662766
info->tcpi_sacked = sk->sk_max_ack_backlog;
27672767
return;
27682768
}
2769+
2770+
slow = lock_sock_fast(sk);
2771+
27692772
info->tcpi_ca_state = icsk->icsk_ca_state;
27702773
info->tcpi_retransmits = icsk->icsk_retransmits;
27712774
info->tcpi_probes = icsk->icsk_probes_out;
@@ -2816,15 +2819,11 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
28162819

28172820
info->tcpi_total_retrans = tp->total_retrans;
28182821

2819-
slow = lock_sock_fast(sk);
2820-
28212822
info->tcpi_bytes_acked = tp->bytes_acked;
28222823
info->tcpi_bytes_received = tp->bytes_received;
28232824
info->tcpi_notsent_bytes = max_t(int, 0, tp->write_seq - tp->snd_nxt);
28242825
tcp_get_info_chrono_stats(tp, info);
28252826

2826-
unlock_sock_fast(sk, slow);
2827-
28282827
info->tcpi_segs_out = tp->segs_out;
28292828
info->tcpi_segs_in = tp->segs_in;
28302829

@@ -2840,6 +2839,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
28402839
do_div(rate64, intv);
28412840
info->tcpi_delivery_rate = rate64;
28422841
}
2842+
unlock_sock_fast(sk, slow);
28432843
}
28442844
EXPORT_SYMBOL_GPL(tcp_get_info);
28452845

0 commit comments

Comments
 (0)