aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/skbuff.h4
-rw-r--r--net/core/datagram.c2
-rw-r--r--net/core/skbuff.c22
-rw-r--r--net/ipv4/arp.c2
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/packet/af_packet.c2
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
423extern void kfree_skb(struct sk_buff *skb); 423extern void kfree_skb(struct sk_buff *skb);
424extern void consume_skb(struct sk_buff *skb);
424extern void __kfree_skb(struct sk_buff *skb); 425extern void __kfree_skb(struct sk_buff *skb);
425extern struct sk_buff *__alloc_skb(unsigned int size, 426extern 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,
459extern int skb_cow_data(struct sk_buff *skb, int tailbits, 460extern int skb_cow_data(struct sk_buff *skb, int tailbits,
460 struct sk_buff **trailer); 461 struct sk_buff **trailer);
461extern int skb_pad(struct sk_buff *skb, int pad); 462extern 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)
463extern void skb_over_panic(struct sk_buff *skb, int len, 465extern void skb_over_panic(struct sk_buff *skb, int len,
464 void *here); 466 void *here);
465extern void skb_under_panic(struct sk_buff *skb, int len, 467extern 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
209void skb_free_datagram(struct sock *sk, struct sk_buff *skb) 209void 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}
447EXPORT_SYMBOL(kfree_skb); 449EXPORT_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 */
459void 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}
469EXPORT_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)
892out: 892out:
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 }
586drop: 586drop:
587 kfree_skb(skb); 587 consume_skb(skb);
588 return 0; 588 return 0;
589} 589}
590 590