]> err.no Git - linux-2.6/blobdiff - include/linux/skbuff.h
Merge master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc
[linux-2.6] / include / linux / skbuff.h
index 1a2611030d369904704ef7bf80b40f98c291a10e..c4619a428d9b11f86648e1971645c2d312a99a8b 100644 (file)
@@ -304,6 +304,7 @@ struct sk_buff {
 
 #include <asm/system.h>
 
+extern void kfree_skb(struct sk_buff *skb);
 extern void           __kfree_skb(struct sk_buff *skb);
 extern struct sk_buff *__alloc_skb(unsigned int size,
                                   gfp_t priority, int fclone);
@@ -403,22 +404,6 @@ static inline struct sk_buff *skb_get(struct sk_buff *skb)
  * atomic change.
  */
 
-/**
- *     kfree_skb - free an sk_buff
- *     @skb: buffer to free
- *
- *     Drop a reference to the buffer and free it if the usage count has
- *     hit zero.
- */
-static inline void kfree_skb(struct sk_buff *skb)
-{
-       if (likely(atomic_read(&skb->users) == 1))
-               smp_rmb();
-       else if (likely(!atomic_dec_and_test(&skb->users)))
-               return;
-       __kfree_skb(skb);
-}
-
 /**
  *     skb_cloned - is the buffer a clone
  *     @skb: buffer to check
@@ -956,6 +941,25 @@ static inline void skb_reserve(struct sk_buff *skb, int len)
 #define NET_IP_ALIGN   2
 #endif
 
+/*
+ * The networking layer reserves some headroom in skb data (via
+ * dev_alloc_skb). This is used to avoid having to reallocate skb data when
+ * the header has to grow. In the default case, if the header has to grow
+ * 16 bytes or less we avoid the reallocation.
+ *
+ * Unfortunately this headroom changes the DMA alignment of the resulting
+ * network packet. As for NET_IP_ALIGN, this unaligned DMA is expensive
+ * on some architectures. An architecture can override this value,
+ * perhaps setting it to a cacheline in size (since that will maintain
+ * cacheline alignment of the DMA). It must be a power of 2.
+ *
+ * Various parts of the networking layer expect at least 16 bytes of
+ * headroom, you should not reduce this.
+ */
+#ifndef NET_SKB_PAD
+#define NET_SKB_PAD    16
+#endif
+
 extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);
 
 static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
@@ -1045,9 +1049,9 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
 static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
                                              gfp_t gfp_mask)
 {
-       struct sk_buff *skb = alloc_skb(length + 16, gfp_mask);
+       struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask);
        if (likely(skb))
-               skb_reserve(skb, 16);
+               skb_reserve(skb, NET_SKB_PAD);
        return skb;
 }
 #else
@@ -1085,13 +1089,15 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length)
  */
 static inline int skb_cow(struct sk_buff *skb, unsigned int headroom)
 {
-       int delta = (headroom > 16 ? headroom : 16) - skb_headroom(skb);
+       int delta = (headroom > NET_SKB_PAD ? headroom : NET_SKB_PAD) -
+                       skb_headroom(skb);
 
        if (delta < 0)
                delta = 0;
 
        if (delta || skb_cloned(skb))
-               return pskb_expand_head(skb, (delta + 15) & ~15, 0, GFP_ATOMIC);
+               return pskb_expand_head(skb, (delta + (NET_SKB_PAD-1)) &
+                               ~(NET_SKB_PAD-1), 0, GFP_ATOMIC);
        return 0;
 }
 
@@ -1174,12 +1180,14 @@ static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
  */
 
 static inline void skb_postpull_rcsum(struct sk_buff *skb,
-                                        const void *start, int len)
+                                     const void *start, unsigned int len)
 {
        if (skb->ip_summed == CHECKSUM_HW)
                skb->csum = csum_sub(skb->csum, csum_partial(start, len, 0));
 }
 
+unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len);
+
 /**
  *     pskb_trim_rcsum - trim received skb and update checksum
  *     @skb: buffer to trim