]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/core/skbuff.c
Revert "Apply SCST exec req fifo patch"
[mv-sheeva.git] / net / core / skbuff.c
index 56ba3c4e4761c6584375a8acf45022bc5c40d6e8..c2b64fbee58ec1e154c57bc677f0e493a1417616 100644 (file)
@@ -76,13 +76,13 @@ static struct kmem_cache *skbuff_fclone_cache __read_mostly;
 static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
                                  struct pipe_buffer *buf)
 {
-       put_page(buf->page);
+       net_put_page(buf->page);
 }
 
 static void sock_pipe_buf_get(struct pipe_inode_info *pipe,
                                struct pipe_buffer *buf)
 {
-       get_page(buf->page);
+       net_get_page(buf->page);
 }
 
 static int sock_pipe_buf_steal(struct pipe_inode_info *pipe,
@@ -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)
 {
@@ -337,10 +324,10 @@ static void skb_release_data(struct sk_buff *skb)
                if (skb_shinfo(skb)->nr_frags) {
                        int i;
                        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-                               put_page(skb_shinfo(skb)->frags[i].page);
+                               net_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 */
@@ -755,12 +730,12 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
 
                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                        skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i];
-                       get_page(skb_shinfo(n)->frags[i].page);
+                       net_get_page(skb_shinfo(n)->frags[i].page);
                }
                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++)
+                       net_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;
@@ -1098,9 +1083,9 @@ drop_pages:
                skb_shinfo(skb)->nr_frags = i;
 
                for (; i < nfrags; i++)
-                       put_page(skb_shinfo(skb)->frags[i].page);
+                       net_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. */
@@ -1267,7 +1252,7 @@ pull_pages:
        k = 0;
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                if (skb_shinfo(skb)->frags[i].size <= eat) {
-                       put_page(skb_shinfo(skb)->frags[i].page);
+                       net_put_page(skb_shinfo(skb)->frags[i].page);
                        eat -= skb_shinfo(skb)->frags[i].size;
                } else {
                        skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i];
@@ -1368,7 +1353,7 @@ EXPORT_SYMBOL(skb_copy_bits);
  */
 static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i)
 {
-       put_page(spd->pages[i]);
+       net_put_page(spd->pages[i]);
 }
 
 static inline struct page *linear_to_page(struct page *page, unsigned int *len,
@@ -1392,7 +1377,7 @@ new_page:
                off = sk->sk_sndmsg_off;
                mlen = PAGE_SIZE - off;
                if (mlen < 64 && mlen < *len) {
-                       put_page(p);
+                       net_put_page(p);
                        goto new_page;
                }
 
@@ -1402,7 +1387,7 @@ new_page:
        memcpy(page_address(p) + off, page_address(page) + *offset, *len);
        sk->sk_sndmsg_off += *len;
        *offset = off;
-       get_page(p);
+       net_get_page(p);
 
        return p;
 }
@@ -1424,7 +1409,7 @@ static inline int spd_fill_page(struct splice_pipe_desc *spd,
                if (!page)
                        return 1;
        } else
-               get_page(page);
+               net_get_page(page);
 
        spd->pages[spd->nr_pages] = page;
        spd->partial[spd->nr_pages].len = *len;
@@ -2057,7 +2042,7 @@ static inline void skb_split_no_header(struct sk_buff *skb,
                                 *    where splitting is expensive.
                                 * 2. Split is accurately. We make this.
                                 */
-                               get_page(skb_shinfo(skb)->frags[i].page);
+                               net_get_page(skb_shinfo(skb)->frags[i].page);
                                skb_shinfo(skb1)->frags[0].page_offset += len - pos;
                                skb_shinfo(skb1)->frags[0].size -= len - pos;
                                skb_shinfo(skb)->frags[i].size  = len - pos;
@@ -2179,7 +2164,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
                        to++;
 
                } else {
-                       get_page(fragfrom->page);
+                       net_get_page(fragfrom->page);
                        fragto->page = fragfrom->page;
                        fragto->page_offset = fragfrom->page_offset;
                        fragto->size = todo;
@@ -2201,7 +2186,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
                fragto = &skb_shinfo(tgt)->frags[merge];
 
                fragto->size += fragfrom->size;
-               put_page(fragfrom->page);
+               net_put_page(fragfrom->page);
        }
 
        /* Reposition in the original skb */
@@ -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;
@@ -2602,7 +2587,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
 
                while (pos < offset + len && i < nfrags) {
                        *frag = skb_shinfo(skb)->frags[i];
-                       get_page(frag->page);
+                       net_get_page(frag->page);
                        size = frag->size;
 
                        if (pos < offset) {
@@ -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();