diff options
author | Hideo Aoki <haoki@redhat.com> | 2007-12-31 03:29:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:00:19 -0500 |
commit | 95766fff6b9a78d11fc2d3812dd035381690b55d (patch) | |
tree | c1ec9386a3d9a76a9f74bd230d3e7d4ee8059c51 /net/ipv6/udp.c | |
parent | 3ab224be6d69de912ee21302745ea45a99274dbc (diff) |
[UDP]: Add memory accounting.
Signed-off-by: Takahiro Yasui <tyasui@redhat.com>
Signed-off-by: Hideo Aoki <haoki@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r-- | net/ipv6/udp.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index c9a97b405511..bf58acab2064 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -204,13 +204,17 @@ try_again: | |||
204 | err = ulen; | 204 | err = ulen; |
205 | 205 | ||
206 | out_free: | 206 | out_free: |
207 | lock_sock(sk); | ||
207 | skb_free_datagram(sk, skb); | 208 | skb_free_datagram(sk, skb); |
209 | release_sock(sk); | ||
208 | out: | 210 | out: |
209 | return err; | 211 | return err; |
210 | 212 | ||
211 | csum_copy_err: | 213 | csum_copy_err: |
214 | lock_sock(sk); | ||
212 | if (!skb_kill_datagram(sk, skb, flags)) | 215 | if (!skb_kill_datagram(sk, skb, flags)) |
213 | UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite); | 216 | UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite); |
217 | release_sock(sk); | ||
214 | 218 | ||
215 | if (flags & MSG_DONTWAIT) | 219 | if (flags & MSG_DONTWAIT) |
216 | return -EAGAIN; | 220 | return -EAGAIN; |
@@ -366,10 +370,21 @@ static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr, | |||
366 | while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr, | 370 | while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr, |
367 | uh->source, saddr, dif))) { | 371 | uh->source, saddr, dif))) { |
368 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); | 372 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); |
369 | if (buff) | 373 | if (buff) { |
370 | udpv6_queue_rcv_skb(sk2, buff); | 374 | bh_lock_sock_nested(sk2); |
375 | if (!sock_owned_by_user(sk2)) | ||
376 | udpv6_queue_rcv_skb(sk2, buff); | ||
377 | else | ||
378 | sk_add_backlog(sk2, buff); | ||
379 | bh_unlock_sock(sk2); | ||
380 | } | ||
371 | } | 381 | } |
372 | udpv6_queue_rcv_skb(sk, skb); | 382 | bh_lock_sock_nested(sk); |
383 | if (!sock_owned_by_user(sk)) | ||
384 | udpv6_queue_rcv_skb(sk, skb); | ||
385 | else | ||
386 | sk_add_backlog(sk, skb); | ||
387 | bh_unlock_sock(sk); | ||
373 | out: | 388 | out: |
374 | read_unlock(&udp_hash_lock); | 389 | read_unlock(&udp_hash_lock); |
375 | return 0; | 390 | return 0; |
@@ -482,7 +497,12 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
482 | 497 | ||
483 | /* deliver */ | 498 | /* deliver */ |
484 | 499 | ||
485 | udpv6_queue_rcv_skb(sk, skb); | 500 | bh_lock_sock_nested(sk); |
501 | if (!sock_owned_by_user(sk)) | ||
502 | udpv6_queue_rcv_skb(sk, skb); | ||
503 | else | ||
504 | sk_add_backlog(sk, skb); | ||
505 | bh_unlock_sock(sk); | ||
486 | sock_put(sk); | 506 | sock_put(sk); |
487 | return 0; | 507 | return 0; |
488 | 508 | ||
@@ -994,6 +1014,10 @@ struct proto udpv6_prot = { | |||
994 | .hash = udp_lib_hash, | 1014 | .hash = udp_lib_hash, |
995 | .unhash = udp_lib_unhash, | 1015 | .unhash = udp_lib_unhash, |
996 | .get_port = udp_v6_get_port, | 1016 | .get_port = udp_v6_get_port, |
1017 | .memory_allocated = &udp_memory_allocated, | ||
1018 | .sysctl_mem = sysctl_udp_mem, | ||
1019 | .sysctl_wmem = &sysctl_udp_wmem_min, | ||
1020 | .sysctl_rmem = &sysctl_udp_rmem_min, | ||
997 | .obj_size = sizeof(struct udp6_sock), | 1021 | .obj_size = sizeof(struct udp6_sock), |
998 | #ifdef CONFIG_COMPAT | 1022 | #ifdef CONFIG_COMPAT |
999 | .compat_setsockopt = compat_udpv6_setsockopt, | 1023 | .compat_setsockopt = compat_udpv6_setsockopt, |