diff options
-rw-r--r-- | include/linux/tcp.h | 2 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 11 | ||||
-rw-r--r-- | net/ipv4/tcp_fastopen.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 4 |
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 | } |
2673 | EXPORT_SYMBOL_GPL(tcp_get_info); | 2676 | EXPORT_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 | ||