Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
[pandora-kernel.git] / net / core / skbuff.c
index 56ba3c4..104f844 100644 (file)
@@ -202,8 +202,6 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
        skb->data = data;
        skb_reset_tail_pointer(skb);
        skb->end = skb->tail + size;
-       kmemcheck_annotate_bitfield(skb, flags1);
-       kmemcheck_annotate_bitfield(skb, flags2);
 #ifdef NET_SKBUFF_DATA_USES_OFFSET
        skb->mac_header = ~0U;
 #endif
@@ -249,10 +247,9 @@ EXPORT_SYMBOL(__alloc_skb);
 struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
                unsigned int length, gfp_t gfp_mask)
 {
-       int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
        struct sk_buff *skb;
 
-       skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node);
+       skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, NUMA_NO_NODE);
        if (likely(skb)) {
                skb_reserve(skb, NET_SKB_PAD);
                skb->dev = dev;
@@ -261,16 +258,6 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
 }
 EXPORT_SYMBOL(__netdev_alloc_skb);
 
-struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask)
-{
-       int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
-       struct page *page;
-
-       page = alloc_pages_node(node, gfp_mask, 0);
-       return page;
-}
-EXPORT_SYMBOL(__netdev_alloc_page);
-
 void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
                int size)
 {
@@ -340,7 +327,7 @@ static void skb_release_data(struct sk_buff *skb)
                                put_page(skb_shinfo(skb)->frags[i].page);
                }
 
-               if (skb_has_frags(skb))
+               if (skb_has_frag_list(skb))
                        skb_drop_fraglist(skb);
 
                kfree(skb->head);
@@ -686,16 +673,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 
 struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
 {
-       int headerlen = skb->data - skb->head;
-       /*
-        *      Allocate the copy buffer
-        */
-       struct sk_buff *n;
-#ifdef NET_SKBUFF_DATA_USES_OFFSET
-       n = alloc_skb(skb->end + skb->data_len, gfp_mask);
-#else
-       n = alloc_skb(skb->end - skb->head + skb->data_len, gfp_mask);
-#endif
+       int headerlen = skb_headroom(skb);
+       unsigned int size = (skb_end_pointer(skb) - skb->head) + skb->data_len;
+       struct sk_buff *n = alloc_skb(size, gfp_mask);
+
        if (!n)
                return NULL;
 
@@ -727,20 +708,14 @@ EXPORT_SYMBOL(skb_copy);
 
 struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
 {
-       /*
-        *      Allocate the copy buffer
-        */
-       struct sk_buff *n;
-#ifdef NET_SKBUFF_DATA_USES_OFFSET
-       n = alloc_skb(skb->end, gfp_mask);
-#else
-       n = alloc_skb(skb->end - skb->head, gfp_mask);
-#endif
+       unsigned int size = skb_end_pointer(skb) - skb->head;
+       struct sk_buff *n = alloc_skb(size, gfp_mask);
+
        if (!n)
                goto out;
 
        /* Set the data pointer */
-       skb_reserve(n, skb->data - skb->head);
+       skb_reserve(n, skb_headroom(skb));
        /* Set the tail pointer and length */
        skb_put(n, skb_headlen(skb));
        /* Copy the bytes */
@@ -760,7 +735,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
                skb_shinfo(n)->nr_frags = i;
        }
 
-       if (skb_has_frags(skb)) {
+       if (skb_has_frag_list(skb)) {
                skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list;
                skb_clone_fraglist(n);
        }
@@ -792,12 +767,9 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
 {
        int i;
        u8 *data;
-#ifdef NET_SKBUFF_DATA_USES_OFFSET
-       int size = nhead + skb->end + ntail;
-#else
-       int size = nhead + (skb->end - skb->head) + ntail;
-#endif
+       int size = nhead + (skb_end_pointer(skb) - skb->head) + ntail;
        long off;
+       bool fastpath;
 
        BUG_ON(nhead < 0);
 
@@ -811,23 +783,36 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
                goto nodata;
 
        /* Copy only real data... and, alas, header. This should be
-        * optimized for the cases when header is void. */
-#ifdef NET_SKBUFF_DATA_USES_OFFSET
-       memcpy(data + nhead, skb->head, skb->tail);
-#else
-       memcpy(data + nhead, skb->head, skb->tail - skb->head);
-#endif
-       memcpy(data + size, skb_end_pointer(skb),
+        * optimized for the cases when header is void.
+        */
+       memcpy(data + nhead, skb->head, skb_tail_pointer(skb) - skb->head);
+
+       memcpy((struct skb_shared_info *)(data + size),
+              skb_shinfo(skb),
               offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags]));
 
-       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-               get_page(skb_shinfo(skb)->frags[i].page);
+       /* Check if we can avoid taking references on fragments if we own
+        * the last reference on skb->head. (see skb_release_data())
+        */
+       if (!skb->cloned)
+               fastpath = true;
+       else {
+               int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1;
 
-       if (skb_has_frags(skb))
-               skb_clone_fraglist(skb);
+               fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta;
+       }
 
-       skb_release_data(skb);
+       if (fastpath) {
+               kfree(skb->head);
+       } else {
+               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+                       get_page(skb_shinfo(skb)->frags[i].page);
 
+               if (skb_has_frag_list(skb))
+                       skb_clone_fraglist(skb);
+
+               skb_release_data(skb);
+       }
        off = (data + nhead) - skb->head;
 
        skb->head     = data;
@@ -1100,7 +1085,7 @@ drop_pages:
                for (; i < nfrags; i++)
                        put_page(skb_shinfo(skb)->frags[i].page);
 
-               if (skb_has_frags(skb))
+               if (skb_has_frag_list(skb))
                        skb_drop_fraglist(skb);
                goto done;
        }
@@ -1195,7 +1180,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta)
        /* Optimization: no fragments, no reasons to preestimate
         * size of pulled pages. Superb.
         */
-       if (!skb_has_frags(skb))
+       if (!skb_has_frag_list(skb))
                goto pull_pages;
 
        /* Estimate size of pulled pages. */
@@ -2324,7 +2309,7 @@ next_skb:
                st->frag_data = NULL;
        }
 
-       if (st->root_skb == st->cur_skb && skb_has_frags(st->root_skb)) {
+       if (st->root_skb == st->cur_skb && skb_has_frag_list(st->root_skb)) {
                st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
                st->frag_idx = 0;
                goto next_skb;
@@ -2894,7 +2879,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
                return -ENOMEM;
 
        /* Easy case. Most of packets will go this way. */
-       if (!skb_has_frags(skb)) {
+       if (!skb_has_frag_list(skb)) {
                /* A little of trouble, not enough of space for trailer.
                 * This should not happen, when stack is tuned to generate
                 * good frames. OK, on miss we reallocate and reserve even more
@@ -2929,7 +2914,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
 
                if (skb1->next == NULL && tailbits) {
                        if (skb_shinfo(skb1)->nr_frags ||
-                           skb_has_frags(skb1) ||
+                           skb_has_frag_list(skb1) ||
                            skb_tailroom(skb1) < tailbits)
                                ntail = tailbits + 128;
                }
@@ -2938,7 +2923,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
                    skb_cloned(skb1) ||
                    ntail ||
                    skb_shinfo(skb1)->nr_frags ||
-                   skb_has_frags(skb1)) {
+                   skb_has_frag_list(skb1)) {
                        struct sk_buff *skb2;
 
                        /* Fuck, we are miserable poor guys... */
@@ -3021,7 +3006,7 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
        } else {
                /*
                 * no hardware time stamps available,
-                * so keep the skb_shared_tx and only
+                * so keep the shared tx_flags and only
                 * store software time stamp
                 */
                skb->tstamp = ktime_get_real();