diff options
author | Neil Horman <nhorman@tuxdriver.com> | 2009-03-11 05:49:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-13 15:09:28 -0400 |
commit | ead2ceb0ec9f85cff19c43b5cdb2f8a054484431 (patch) | |
tree | 258874b824bf241698d943daa9298bb18955e451 | |
parent | 4893d39e865b2897bf9fcd329697d37032d853a1 (diff) |
Network Drop Monitor: Adding kfree_skb_clean for non-drops and modifying end-of-line points for skbs
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
include/linux/skbuff.h | 4 +++-
net/core/datagram.c | 2 +-
net/core/skbuff.c | 22 ++++++++++++++++++++++
net/ipv4/arp.c | 2 +-
net/ipv4/udp.c | 2 +-
net/packet/af_packet.c | 2 +-
6 files changed, 29 insertions(+), 5 deletions(-)
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/skbuff.h | 4 | ||||
-rw-r--r-- | net/core/datagram.c | 2 | ||||
-rw-r--r-- | net/core/skbuff.c | 22 | ||||
-rw-r--r-- | net/ipv4/arp.c | 2 | ||||
-rw-r--r-- | net/ipv4/udp.c | 2 | ||||
-rw-r--r-- | net/packet/af_packet.c | 2 |
6 files changed, 29 insertions, 5 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 1f659e8c2b88..1fbab2ae613c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -421,6 +421,7 @@ extern void skb_dma_unmap(struct device *dev, struct sk_buff *skb, | |||
421 | #endif | 421 | #endif |
422 | 422 | ||
423 | extern void kfree_skb(struct sk_buff *skb); | 423 | extern void kfree_skb(struct sk_buff *skb); |
424 | extern void consume_skb(struct sk_buff *skb); | ||
424 | extern void __kfree_skb(struct sk_buff *skb); | 425 | extern void __kfree_skb(struct sk_buff *skb); |
425 | extern struct sk_buff *__alloc_skb(unsigned int size, | 426 | extern struct sk_buff *__alloc_skb(unsigned int size, |
426 | gfp_t priority, int fclone, int node); | 427 | gfp_t priority, int fclone, int node); |
@@ -459,7 +460,8 @@ extern int skb_to_sgvec(struct sk_buff *skb, | |||
459 | extern int skb_cow_data(struct sk_buff *skb, int tailbits, | 460 | extern int skb_cow_data(struct sk_buff *skb, int tailbits, |
460 | struct sk_buff **trailer); | 461 | struct sk_buff **trailer); |
461 | extern int skb_pad(struct sk_buff *skb, int pad); | 462 | extern int skb_pad(struct sk_buff *skb, int pad); |
462 | #define dev_kfree_skb(a) kfree_skb(a) | 463 | #define dev_kfree_skb(a) consume_skb(a) |
464 | #define dev_consume_skb(a) kfree_skb_clean(a) | ||
463 | extern void skb_over_panic(struct sk_buff *skb, int len, | 465 | extern void skb_over_panic(struct sk_buff *skb, int len, |
464 | void *here); | 466 | void *here); |
465 | extern void skb_under_panic(struct sk_buff *skb, int len, | 467 | extern void skb_under_panic(struct sk_buff *skb, int len, |
diff --git a/net/core/datagram.c b/net/core/datagram.c index 5e2ac0c4b07c..d0de644b378d 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -208,7 +208,7 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, | |||
208 | 208 | ||
209 | void skb_free_datagram(struct sock *sk, struct sk_buff *skb) | 209 | void skb_free_datagram(struct sock *sk, struct sk_buff *skb) |
210 | { | 210 | { |
211 | kfree_skb(skb); | 211 | consume_skb(skb); |
212 | sk_mem_reclaim_partial(sk); | 212 | sk_mem_reclaim_partial(sk); |
213 | } | 213 | } |
214 | 214 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index e5e2111a397d..6acbf9e79eb1 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -65,6 +65,7 @@ | |||
65 | 65 | ||
66 | #include <asm/uaccess.h> | 66 | #include <asm/uaccess.h> |
67 | #include <asm/system.h> | 67 | #include <asm/system.h> |
68 | #include <trace/skb.h> | ||
68 | 69 | ||
69 | #include "kmap_skb.h" | 70 | #include "kmap_skb.h" |
70 | 71 | ||
@@ -442,11 +443,32 @@ void kfree_skb(struct sk_buff *skb) | |||
442 | smp_rmb(); | 443 | smp_rmb(); |
443 | else if (likely(!atomic_dec_and_test(&skb->users))) | 444 | else if (likely(!atomic_dec_and_test(&skb->users))) |
444 | return; | 445 | return; |
446 | trace_kfree_skb(skb, __builtin_return_address(0)); | ||
445 | __kfree_skb(skb); | 447 | __kfree_skb(skb); |
446 | } | 448 | } |
447 | EXPORT_SYMBOL(kfree_skb); | 449 | EXPORT_SYMBOL(kfree_skb); |
448 | 450 | ||
449 | /** | 451 | /** |
452 | * consume_skb - free an skbuff | ||
453 | * @skb: buffer to free | ||
454 | * | ||
455 | * Drop a ref to the buffer and free it if the usage count has hit zero | ||
456 | * Functions identically to kfree_skb, but kfree_skb assumes that the frame | ||
457 | * is being dropped after a failure and notes that | ||
458 | */ | ||
459 | void consume_skb(struct sk_buff *skb) | ||
460 | { | ||
461 | if (unlikely(!skb)) | ||
462 | return; | ||
463 | if (likely(atomic_read(&skb->users) == 1)) | ||
464 | smp_rmb(); | ||
465 | else if (likely(!atomic_dec_and_test(&skb->users))) | ||
466 | return; | ||
467 | __kfree_skb(skb); | ||
468 | } | ||
469 | EXPORT_SYMBOL(consume_skb); | ||
470 | |||
471 | /** | ||
450 | * skb_recycle_check - check if skb can be reused for receive | 472 | * skb_recycle_check - check if skb can be reused for receive |
451 | * @skb: buffer | 473 | * @skb: buffer |
452 | * @skb_size: minimum receive buffer size | 474 | * @skb_size: minimum receive buffer size |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 3d67d1ffed77..9c220323f353 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -892,7 +892,7 @@ static int arp_process(struct sk_buff *skb) | |||
892 | out: | 892 | out: |
893 | if (in_dev) | 893 | if (in_dev) |
894 | in_dev_put(in_dev); | 894 | in_dev_put(in_dev); |
895 | kfree_skb(skb); | 895 | consume_skb(skb); |
896 | return 0; | 896 | return 0; |
897 | } | 897 | } |
898 | 898 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 4bd178a111d5..05b7abb99f69 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1184,7 +1184,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | |||
1184 | sk = sknext; | 1184 | sk = sknext; |
1185 | } while (sknext); | 1185 | } while (sknext); |
1186 | } else | 1186 | } else |
1187 | kfree_skb(skb); | 1187 | consume_skb(skb); |
1188 | spin_unlock(&hslot->lock); | 1188 | spin_unlock(&hslot->lock); |
1189 | return 0; | 1189 | return 0; |
1190 | } | 1190 | } |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index d8cc006fac45..74776de523ec 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -584,7 +584,7 @@ drop_n_restore: | |||
584 | skb->len = skb_len; | 584 | skb->len = skb_len; |
585 | } | 585 | } |
586 | drop: | 586 | drop: |
587 | kfree_skb(skb); | 587 | consume_skb(skb); |
588 | return 0; | 588 | return 0; |
589 | } | 589 | } |
590 | 590 | ||