aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/tcp.h2
-rw-r--r--net/ipv4/tcp.c11
-rw-r--r--net/ipv4/tcp_fastopen.c4
-rw-r--r--net/ipv4/tcp_input.c4
4 files changed, 17 insertions, 4 deletions
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 3b2911502a8c..e8bbf403618f 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -158,6 +158,8 @@ struct tcp_sock {
158 * sum(delta(snd_una)), or how many bytes 158 * sum(delta(snd_una)), or how many bytes
159 * were acked. 159 * were acked.
160 */ 160 */
161 struct u64_stats_sync syncp; /* protects 64bit vars (cf tcp_get_info()) */
162
161 u32 snd_una; /* First byte we want an ack for */ 163 u32 snd_una; /* First byte we want an ack for */
162 u32 snd_sml; /* Last byte of the most recently transmitted small packet */ 164 u32 snd_sml; /* Last byte of the most recently transmitted small packet */
163 u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */ 165 u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 46efa03d2b11..f1377f2a0472 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -402,6 +402,7 @@ void tcp_init_sock(struct sock *sk)
402 tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; 402 tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
403 tp->snd_cwnd_clamp = ~0; 403 tp->snd_cwnd_clamp = ~0;
404 tp->mss_cache = TCP_MSS_DEFAULT; 404 tp->mss_cache = TCP_MSS_DEFAULT;
405 u64_stats_init(&tp->syncp);
405 406
406 tp->reordering = sysctl_tcp_reordering; 407 tp->reordering = sysctl_tcp_reordering;
407 tcp_enable_early_retrans(tp); 408 tcp_enable_early_retrans(tp);
@@ -2598,6 +2599,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
2598 const struct tcp_sock *tp = tcp_sk(sk); 2599 const struct tcp_sock *tp = tcp_sk(sk);
2599 const struct inet_connection_sock *icsk = inet_csk(sk); 2600 const struct inet_connection_sock *icsk = inet_csk(sk);
2600 u32 now = tcp_time_stamp; 2601 u32 now = tcp_time_stamp;
2602 unsigned int start;
2601 u32 rate; 2603 u32 rate;
2602 2604
2603 memset(info, 0, sizeof(*info)); 2605 memset(info, 0, sizeof(*info));
@@ -2665,10 +2667,11 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
2665 rate = READ_ONCE(sk->sk_max_pacing_rate); 2667 rate = READ_ONCE(sk->sk_max_pacing_rate);
2666 info->tcpi_max_pacing_rate = rate != ~0U ? rate : ~0ULL; 2668 info->tcpi_max_pacing_rate = rate != ~0U ? rate : ~0ULL;
2667 2669
2668 spin_lock_bh(&sk->sk_lock.slock); 2670 do {
2669 info->tcpi_bytes_acked = tp->bytes_acked; 2671 start = u64_stats_fetch_begin_irq(&tp->syncp);
2670 info->tcpi_bytes_received = tp->bytes_received; 2672 info->tcpi_bytes_acked = tp->bytes_acked;
2671 spin_unlock_bh(&sk->sk_lock.slock); 2673 info->tcpi_bytes_received = tp->bytes_received;
2674 } while (u64_stats_fetch_retry_irq(&tp->syncp, start));
2672} 2675}
2673EXPORT_SYMBOL_GPL(tcp_get_info); 2676EXPORT_SYMBOL_GPL(tcp_get_info);
2674 2677
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 3c673d5e6cff..46b087a27503 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -206,6 +206,10 @@ static bool tcp_fastopen_create_child(struct sock *sk,
206 skb_set_owner_r(skb2, child); 206 skb_set_owner_r(skb2, child);
207 __skb_queue_tail(&child->sk_receive_queue, skb2); 207 __skb_queue_tail(&child->sk_receive_queue, skb2);
208 tp->syn_data_acked = 1; 208 tp->syn_data_acked = 1;
209
210 /* u64_stats_update_begin(&tp->syncp) not needed here,
211 * as we certainly are not changing upper 32bit value (0)
212 */
209 tp->bytes_received = end_seq - TCP_SKB_CB(skb)->seq - 1; 213 tp->bytes_received = end_seq - TCP_SKB_CB(skb)->seq - 1;
210 } else { 214 } else {
211 end_seq = TCP_SKB_CB(skb)->seq + 1; 215 end_seq = TCP_SKB_CB(skb)->seq + 1;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 243d674b3ef5..c9ab964189a0 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3286,7 +3286,9 @@ static void tcp_snd_una_update(struct tcp_sock *tp, u32 ack)
3286{ 3286{
3287 u32 delta = ack - tp->snd_una; 3287 u32 delta = ack - tp->snd_una;
3288 3288
3289 u64_stats_update_begin(&tp->syncp);
3289 tp->bytes_acked += delta; 3290 tp->bytes_acked += delta;
3291 u64_stats_update_end(&tp->syncp);
3290 tp->snd_una = ack; 3292 tp->snd_una = ack;
3291} 3293}
3292 3294
@@ -3295,7 +3297,9 @@ static void tcp_rcv_nxt_update(struct tcp_sock *tp, u32 seq)
3295{ 3297{
3296 u32 delta = seq - tp->rcv_nxt; 3298 u32 delta = seq - tp->rcv_nxt;
3297 3299
3300 u64_stats_update_begin(&tp->syncp);
3298 tp->bytes_received += delta; 3301 tp->bytes_received += delta;
3302 u64_stats_update_end(&tp->syncp);
3299 tp->rcv_nxt = seq; 3303 tp->rcv_nxt = seq;
3300} 3304}
3301 3305