diff options
| author | Eric Dumazet <edumazet@google.com> | 2019-10-10 23:17:46 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2019-10-13 13:13:08 -0400 |
| commit | ab4e846a82d0ae00176de19f2db3c5c64f8eb5f2 (patch) | |
| tree | 7be26ef02ab2f2979be9a3cdeb36ed1bafc51354 /net | |
| parent | e292f05e0df73f9fcc93329663936e1ded97a988 (diff) | |
tcp: annotate sk->sk_wmem_queued lockless reads
For the sake of tcp_poll(), there are few places where we fetch
sk->sk_wmem_queued while this field can change from IRQ or other cpu.
We need to add READ_ONCE() annotations, and also make sure write
sides use corresponding WRITE_ONCE() to avoid store-tearing.
sk_wmem_queued_add() helper is added so that we can in
the future convert to ADD_ONCE() or equivalent if/when
available.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
| -rw-r--r-- | net/core/datagram.c | 2 | ||||
| -rw-r--r-- | net/core/sock.c | 2 | ||||
| -rw-r--r-- | net/ipv4/inet_diag.c | 2 | ||||
| -rw-r--r-- | net/ipv4/tcp.c | 4 | ||||
| -rw-r--r-- | net/ipv4/tcp_output.c | 14 | ||||
| -rw-r--r-- | net/sched/em_meta.c | 2 |
6 files changed, 13 insertions, 13 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c index 4cc8dc5db2b7..c210fc116103 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
| @@ -640,7 +640,7 @@ int __zerocopy_sg_from_iter(struct sock *sk, struct sk_buff *skb, | |||
| 640 | skb->len += copied; | 640 | skb->len += copied; |
| 641 | skb->truesize += truesize; | 641 | skb->truesize += truesize; |
| 642 | if (sk && sk->sk_type == SOCK_STREAM) { | 642 | if (sk && sk->sk_type == SOCK_STREAM) { |
| 643 | sk->sk_wmem_queued += truesize; | 643 | sk_wmem_queued_add(sk, truesize); |
| 644 | sk_mem_charge(sk, truesize); | 644 | sk_mem_charge(sk, truesize); |
| 645 | } else { | 645 | } else { |
| 646 | refcount_add(truesize, &skb->sk->sk_wmem_alloc); | 646 | refcount_add(truesize, &skb->sk->sk_wmem_alloc); |
diff --git a/net/core/sock.c b/net/core/sock.c index cd075bc86407..a515392ba84b 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -3212,7 +3212,7 @@ void sk_get_meminfo(const struct sock *sk, u32 *mem) | |||
| 3212 | mem[SK_MEMINFO_WMEM_ALLOC] = sk_wmem_alloc_get(sk); | 3212 | mem[SK_MEMINFO_WMEM_ALLOC] = sk_wmem_alloc_get(sk); |
| 3213 | mem[SK_MEMINFO_SNDBUF] = READ_ONCE(sk->sk_sndbuf); | 3213 | mem[SK_MEMINFO_SNDBUF] = READ_ONCE(sk->sk_sndbuf); |
| 3214 | mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc; | 3214 | mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc; |
| 3215 | mem[SK_MEMINFO_WMEM_QUEUED] = sk->sk_wmem_queued; | 3215 | mem[SK_MEMINFO_WMEM_QUEUED] = READ_ONCE(sk->sk_wmem_queued); |
| 3216 | mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc); | 3216 | mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc); |
| 3217 | mem[SK_MEMINFO_BACKLOG] = READ_ONCE(sk->sk_backlog.len); | 3217 | mem[SK_MEMINFO_BACKLOG] = READ_ONCE(sk->sk_backlog.len); |
| 3218 | mem[SK_MEMINFO_DROPS] = atomic_read(&sk->sk_drops); | 3218 | mem[SK_MEMINFO_DROPS] = atomic_read(&sk->sk_drops); |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index bbb005eb5218..7dc79b973e6e 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -193,7 +193,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | |||
| 193 | if (ext & (1 << (INET_DIAG_MEMINFO - 1))) { | 193 | if (ext & (1 << (INET_DIAG_MEMINFO - 1))) { |
| 194 | struct inet_diag_meminfo minfo = { | 194 | struct inet_diag_meminfo minfo = { |
| 195 | .idiag_rmem = sk_rmem_alloc_get(sk), | 195 | .idiag_rmem = sk_rmem_alloc_get(sk), |
| 196 | .idiag_wmem = sk->sk_wmem_queued, | 196 | .idiag_wmem = READ_ONCE(sk->sk_wmem_queued), |
| 197 | .idiag_fmem = sk->sk_forward_alloc, | 197 | .idiag_fmem = sk->sk_forward_alloc, |
| 198 | .idiag_tmem = sk_wmem_alloc_get(sk), | 198 | .idiag_tmem = sk_wmem_alloc_get(sk), |
| 199 | }; | 199 | }; |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 111853262972..b2ac4f074e2d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -659,7 +659,7 @@ static void skb_entail(struct sock *sk, struct sk_buff *skb) | |||
| 659 | tcb->sacked = 0; | 659 | tcb->sacked = 0; |
| 660 | __skb_header_release(skb); | 660 | __skb_header_release(skb); |
| 661 | tcp_add_write_queue_tail(sk, skb); | 661 | tcp_add_write_queue_tail(sk, skb); |
| 662 | sk->sk_wmem_queued += skb->truesize; | 662 | sk_wmem_queued_add(sk, skb->truesize); |
| 663 | sk_mem_charge(sk, skb->truesize); | 663 | sk_mem_charge(sk, skb->truesize); |
| 664 | if (tp->nonagle & TCP_NAGLE_PUSH) | 664 | if (tp->nonagle & TCP_NAGLE_PUSH) |
| 665 | tp->nonagle &= ~TCP_NAGLE_PUSH; | 665 | tp->nonagle &= ~TCP_NAGLE_PUSH; |
| @@ -1034,7 +1034,7 @@ new_segment: | |||
| 1034 | skb->len += copy; | 1034 | skb->len += copy; |
| 1035 | skb->data_len += copy; | 1035 | skb->data_len += copy; |
| 1036 | skb->truesize += copy; | 1036 | skb->truesize += copy; |
| 1037 | sk->sk_wmem_queued += copy; | 1037 | sk_wmem_queued_add(sk, copy); |
| 1038 | sk_mem_charge(sk, copy); | 1038 | sk_mem_charge(sk, copy); |
| 1039 | skb->ip_summed = CHECKSUM_PARTIAL; | 1039 | skb->ip_summed = CHECKSUM_PARTIAL; |
| 1040 | WRITE_ONCE(tp->write_seq, tp->write_seq + copy); | 1040 | WRITE_ONCE(tp->write_seq, tp->write_seq + copy); |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index a115a991dfb5..0488607c5cd3 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -1199,7 +1199,7 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) | |||
| 1199 | WRITE_ONCE(tp->write_seq, TCP_SKB_CB(skb)->end_seq); | 1199 | WRITE_ONCE(tp->write_seq, TCP_SKB_CB(skb)->end_seq); |
| 1200 | __skb_header_release(skb); | 1200 | __skb_header_release(skb); |
| 1201 | tcp_add_write_queue_tail(sk, skb); | 1201 | tcp_add_write_queue_tail(sk, skb); |
| 1202 | sk->sk_wmem_queued += skb->truesize; | 1202 | sk_wmem_queued_add(sk, skb->truesize); |
| 1203 | sk_mem_charge(sk, skb->truesize); | 1203 | sk_mem_charge(sk, skb->truesize); |
| 1204 | } | 1204 | } |
| 1205 | 1205 | ||
| @@ -1333,7 +1333,7 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue, | |||
| 1333 | return -ENOMEM; /* We'll just try again later. */ | 1333 | return -ENOMEM; /* We'll just try again later. */ |
| 1334 | skb_copy_decrypted(buff, skb); | 1334 | skb_copy_decrypted(buff, skb); |
| 1335 | 1335 | ||
| 1336 | sk->sk_wmem_queued += buff->truesize; | 1336 | sk_wmem_queued_add(sk, buff->truesize); |
| 1337 | sk_mem_charge(sk, buff->truesize); | 1337 | sk_mem_charge(sk, buff->truesize); |
| 1338 | nlen = skb->len - len - nsize; | 1338 | nlen = skb->len - len - nsize; |
| 1339 | buff->truesize += nlen; | 1339 | buff->truesize += nlen; |
| @@ -1443,7 +1443,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) | |||
| 1443 | 1443 | ||
| 1444 | if (delta_truesize) { | 1444 | if (delta_truesize) { |
| 1445 | skb->truesize -= delta_truesize; | 1445 | skb->truesize -= delta_truesize; |
| 1446 | sk->sk_wmem_queued -= delta_truesize; | 1446 | sk_wmem_queued_add(sk, -delta_truesize); |
| 1447 | sk_mem_uncharge(sk, delta_truesize); | 1447 | sk_mem_uncharge(sk, delta_truesize); |
| 1448 | sock_set_flag(sk, SOCK_QUEUE_SHRUNK); | 1448 | sock_set_flag(sk, SOCK_QUEUE_SHRUNK); |
| 1449 | } | 1449 | } |
| @@ -1888,7 +1888,7 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len, | |||
| 1888 | return -ENOMEM; | 1888 | return -ENOMEM; |
| 1889 | skb_copy_decrypted(buff, skb); | 1889 | skb_copy_decrypted(buff, skb); |
| 1890 | 1890 | ||
| 1891 | sk->sk_wmem_queued += buff->truesize; | 1891 | sk_wmem_queued_add(sk, buff->truesize); |
| 1892 | sk_mem_charge(sk, buff->truesize); | 1892 | sk_mem_charge(sk, buff->truesize); |
| 1893 | buff->truesize += nlen; | 1893 | buff->truesize += nlen; |
| 1894 | skb->truesize -= nlen; | 1894 | skb->truesize -= nlen; |
| @@ -2152,7 +2152,7 @@ static int tcp_mtu_probe(struct sock *sk) | |||
| 2152 | nskb = sk_stream_alloc_skb(sk, probe_size, GFP_ATOMIC, false); | 2152 | nskb = sk_stream_alloc_skb(sk, probe_size, GFP_ATOMIC, false); |
| 2153 | if (!nskb) | 2153 | if (!nskb) |
| 2154 | return -1; | 2154 | return -1; |
| 2155 | sk->sk_wmem_queued += nskb->truesize; | 2155 | sk_wmem_queued_add(sk, nskb->truesize); |
| 2156 | sk_mem_charge(sk, nskb->truesize); | 2156 | sk_mem_charge(sk, nskb->truesize); |
| 2157 | 2157 | ||
| 2158 | skb = tcp_send_head(sk); | 2158 | skb = tcp_send_head(sk); |
| @@ -3222,7 +3222,7 @@ int tcp_send_synack(struct sock *sk) | |||
| 3222 | tcp_rtx_queue_unlink_and_free(skb, sk); | 3222 | tcp_rtx_queue_unlink_and_free(skb, sk); |
| 3223 | __skb_header_release(nskb); | 3223 | __skb_header_release(nskb); |
| 3224 | tcp_rbtree_insert(&sk->tcp_rtx_queue, nskb); | 3224 | tcp_rbtree_insert(&sk->tcp_rtx_queue, nskb); |
| 3225 | sk->sk_wmem_queued += nskb->truesize; | 3225 | sk_wmem_queued_add(sk, nskb->truesize); |
| 3226 | sk_mem_charge(sk, nskb->truesize); | 3226 | sk_mem_charge(sk, nskb->truesize); |
| 3227 | skb = nskb; | 3227 | skb = nskb; |
| 3228 | } | 3228 | } |
| @@ -3447,7 +3447,7 @@ static void tcp_connect_queue_skb(struct sock *sk, struct sk_buff *skb) | |||
| 3447 | 3447 | ||
| 3448 | tcb->end_seq += skb->len; | 3448 | tcb->end_seq += skb->len; |
| 3449 | __skb_header_release(skb); | 3449 | __skb_header_release(skb); |
| 3450 | sk->sk_wmem_queued += skb->truesize; | 3450 | sk_wmem_queued_add(sk, skb->truesize); |
| 3451 | sk_mem_charge(sk, skb->truesize); | 3451 | sk_mem_charge(sk, skb->truesize); |
| 3452 | WRITE_ONCE(tp->write_seq, tcb->end_seq); | 3452 | WRITE_ONCE(tp->write_seq, tcb->end_seq); |
| 3453 | tp->packets_out += tcp_skb_pcount(skb); | 3453 | tp->packets_out += tcp_skb_pcount(skb); |
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 4c9122fc35c9..3177dcb17316 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c | |||
| @@ -446,7 +446,7 @@ META_COLLECTOR(int_sk_wmem_queued) | |||
| 446 | *err = -1; | 446 | *err = -1; |
| 447 | return; | 447 | return; |
| 448 | } | 448 | } |
| 449 | dst->value = sk->sk_wmem_queued; | 449 | dst->value = READ_ONCE(sk->sk_wmem_queued); |
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | META_COLLECTOR(int_sk_fwd_alloc) | 452 | META_COLLECTOR(int_sk_fwd_alloc) |
