aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2019-10-10 23:17:46 -0400
committerDavid S. Miller <davem@davemloft.net>2019-10-13 13:13:08 -0400
commitab4e846a82d0ae00176de19f2db3c5c64f8eb5f2 (patch)
tree7be26ef02ab2f2979be9a3cdeb36ed1bafc51354 /net
parente292f05e0df73f9fcc93329663936e1ded97a988 (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.c2
-rw-r--r--net/core/sock.c2
-rw-r--r--net/ipv4/inet_diag.c2
-rw-r--r--net/ipv4/tcp.c4
-rw-r--r--net/ipv4/tcp_output.c14
-rw-r--r--net/sched/em_meta.c2
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
452META_COLLECTOR(int_sk_fwd_alloc) 452META_COLLECTOR(int_sk_fwd_alloc)