perf hist: fix objdump output parsing
[safe/jmp/linux-2.6] / net / core / skbuff.c
index b94d777..f8abf68 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/kmemcheck.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/in.h>
@@ -65,7 +66,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <trace/skb.h>
+#include <trace/events/skb.h>
 
 #include "kmap_skb.h"
 
@@ -92,7 +93,7 @@ static int sock_pipe_buf_steal(struct pipe_inode_info *pipe,
 
 
 /* Pipe buffer operations for a socket. */
-static struct pipe_buf_operations sock_pipe_buf_ops = {
+static const struct pipe_buf_operations sock_pipe_buf_ops = {
        .can_merge = 0,
        .map = generic_pipe_buf_map,
        .unmap = generic_pipe_buf_unmap,
@@ -116,7 +117,7 @@ static struct pipe_buf_operations sock_pipe_buf_ops = {
  *
  *     Out of line support code for skb_put(). Not user callable.
  */
-void skb_over_panic(struct sk_buff *skb, int sz, void *here)
+static void skb_over_panic(struct sk_buff *skb, int sz, void *here)
 {
        printk(KERN_EMERG "skb_over_panic: text:%p len:%d put:%d head:%p "
                          "data:%p tail:%#lx end:%#lx dev:%s\n",
@@ -125,7 +126,6 @@ void skb_over_panic(struct sk_buff *skb, int sz, void *here)
               skb->dev ? skb->dev->name : "<NULL>");
        BUG();
 }
-EXPORT_SYMBOL(skb_over_panic);
 
 /**
  *     skb_under_panic -       private function
@@ -136,7 +136,7 @@ EXPORT_SYMBOL(skb_over_panic);
  *     Out of line support code for skb_push(). Not user callable.
  */
 
-void skb_under_panic(struct sk_buff *skb, int sz, void *here)
+static void skb_under_panic(struct sk_buff *skb, int sz, void *here)
 {
        printk(KERN_EMERG "skb_under_panic: text:%p len:%d put:%d head:%p "
                          "data:%p tail:%#lx end:%#lx dev:%s\n",
@@ -145,7 +145,6 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here)
               skb->dev ? skb->dev->name : "<NULL>");
        BUG();
 }
-EXPORT_SYMBOL(skb_under_panic);
 
 /*     Allocate a new skbuff. We do this ourselves so we can fill in a few
  *     'private' fields and also do memory statistics to find all the
@@ -182,12 +181,14 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
        skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node);
        if (!skb)
                goto out;
+       prefetchw(skb);
 
        size = SKB_DATA_ALIGN(size);
        data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info),
                        gfp_mask, node);
        if (!data)
                goto nodata;
+       prefetchw(data + size);
 
        /*
         * Only clear those fields we need to clear, not those that we will
@@ -201,22 +202,23 @@ 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
+
        /* make sure we initialize shinfo sequentially */
        shinfo = skb_shinfo(skb);
+       memset(shinfo, 0, offsetof(struct skb_shared_info, dataref));
        atomic_set(&shinfo->dataref, 1);
-       shinfo->nr_frags  = 0;
-       shinfo->gso_size = 0;
-       shinfo->gso_segs = 0;
-       shinfo->gso_type = 0;
-       shinfo->ip6_frag_id = 0;
-       shinfo->tx_flags.flags = 0;
-       skb_frag_list_init(skb);
-       memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps));
 
        if (fclone) {
                struct sk_buff *child = skb + 1;
                atomic_t *fclone_ref = (atomic_t *) (child + 1);
 
+               kmemcheck_annotate_bitfield(child, flags1);
+               kmemcheck_annotate_bitfield(child, flags2);
                skb->fclone = SKB_FCLONE_ORIG;
                atomic_set(fclone_ref, 1);
 
@@ -484,6 +486,9 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size)
 {
        struct skb_shared_info *shinfo;
 
+       if (irqs_disabled())
+               return 0;
+
        if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE)
                return 0;
 
@@ -495,16 +500,10 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size)
                return 0;
 
        skb_release_head_state(skb);
+
        shinfo = skb_shinfo(skb);
+       memset(shinfo, 0, offsetof(struct skb_shared_info, dataref));
        atomic_set(&shinfo->dataref, 1);
-       shinfo->nr_frags = 0;
-       shinfo->gso_size = 0;
-       shinfo->gso_segs = 0;
-       shinfo->gso_type = 0;
-       shinfo->ip6_frag_id = 0;
-       shinfo->tx_flags.flags = 0;
-       skb_frag_list_init(skb);
-       memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps));
 
        memset(skb, 0, offsetof(struct sk_buff, tail));
        skb->data = skb->head + NET_SKB_PAD;
@@ -521,7 +520,8 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        new->transport_header   = old->transport_header;
        new->network_header     = old->network_header;
        new->mac_header         = old->mac_header;
-       skb_dst_set(new, dst_clone(skb_dst(old)));
+       skb_dst_copy(new, old);
+       new->rxhash             = old->rxhash;
 #ifdef CONFIG_XFRM
        new->sp                 = secpath_get(old->sp);
 #endif
@@ -537,7 +537,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 #endif
        new->protocol           = old->protocol;
        new->mark               = old->mark;
-       new->iif                = old->iif;
+       new->skb_iif            = old->skb_iif;
        __nf_copy(new, old);
 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
@@ -550,9 +550,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 #endif
 #endif
        new->vlan_tci           = old->vlan_tci;
-#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
-       new->do_not_encrypt     = old->do_not_encrypt;
-#endif
 
        skb_copy_secmark(new, old);
 }
@@ -572,6 +569,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
        C(len);
        C(data_len);
        C(mac_len);
+       C(rxhash);
        n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
        n->cloned = 1;
        n->nohdr = 0;
@@ -635,6 +633,9 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
                n = kmem_cache_alloc(skbuff_head_cache, gfp_mask);
                if (!n)
                        return NULL;
+
+               kmemcheck_annotate_bitfield(n, flags1);
+               kmemcheck_annotate_bitfield(n, flags2);
                n->fclone = SKB_FCLONE_UNAVAILABLE;
        }
 
@@ -657,7 +658,8 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        /* {transport,network,mac}_header are relative to skb->head */
        new->transport_header += offset;
        new->network_header   += offset;
-       new->mac_header       += offset;
+       if (skb_mac_header_was_set(new))
+               new->mac_header       += offset;
 #endif
        skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
        skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
@@ -839,7 +841,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
        skb->tail             += off;
        skb->transport_header += off;
        skb->network_header   += off;
-       skb->mac_header       += off;
+       if (skb_mac_header_was_set(skb))
+               skb->mac_header += off;
        skb->csum_start       += nhead;
        skb->cloned   = 0;
        skb->hdr_len  = 0;
@@ -931,7 +934,8 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
 #ifdef NET_SKBUFF_DATA_USES_OFFSET
        n->transport_header += off;
        n->network_header   += off;
-       n->mac_header       += off;
+       if (skb_mac_header_was_set(skb))
+               n->mac_header += off;
 #endif
 
        return n;
@@ -1036,7 +1040,7 @@ EXPORT_SYMBOL(skb_push);
  */
 unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
 {
-       return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
+       return skb_pull_inline(skb, len);
 }
 EXPORT_SYMBOL(skb_pull);
 
@@ -1402,12 +1406,13 @@ new_page:
 /*
  * Fill page/offset/length into spd, if it can hold more pages.
  */
-static inline int spd_fill_page(struct splice_pipe_desc *spd, struct page *page,
+static inline int spd_fill_page(struct splice_pipe_desc *spd,
+                               struct pipe_inode_info *pipe, struct page *page,
                                unsigned int *len, unsigned int offset,
                                struct sk_buff *skb, int linear,
                                struct sock *sk)
 {
-       if (unlikely(spd->nr_pages == PIPE_BUFFERS))
+       if (unlikely(spd->nr_pages == pipe->buffers))
                return 1;
 
        if (linear) {
@@ -1443,7 +1448,8 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
                                   unsigned int plen, unsigned int *off,
                                   unsigned int *len, struct sk_buff *skb,
                                   struct splice_pipe_desc *spd, int linear,
-                                  struct sock *sk)
+                                  struct sock *sk,
+                                  struct pipe_inode_info *pipe)
 {
        if (!*len)
                return 1;
@@ -1466,7 +1472,7 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
                /* the linear region may spread across several pages  */
                flen = min_t(unsigned int, flen, PAGE_SIZE - poff);
 
-               if (spd_fill_page(spd, page, &flen, poff, skb, linear, sk))
+               if (spd_fill_page(spd, pipe, page, &flen, poff, skb, linear, sk))
                        return 1;
 
                __segment_seek(&page, &poff, &plen, flen);
@@ -1481,9 +1487,9 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
  * Map linear and fragment data from the skb to spd. It reports failure if the
  * pipe is full or if we already spliced the requested length.
  */
-static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
-                            unsigned int *len, struct splice_pipe_desc *spd,
-                            struct sock *sk)
+static int __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
+                            unsigned int *offset, unsigned int *len,
+                            struct splice_pipe_desc *spd, struct sock *sk)
 {
        int seg;
 
@@ -1493,7 +1499,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
        if (__splice_segment(virt_to_page(skb->data),
                             (unsigned long) skb->data & (PAGE_SIZE - 1),
                             skb_headlen(skb),
-                            offset, len, skb, spd, 1, sk))
+                            offset, len, skb, spd, 1, sk, pipe))
                return 1;
 
        /*
@@ -1503,7 +1509,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
                const skb_frag_t *f = &skb_shinfo(skb)->frags[seg];
 
                if (__splice_segment(f->page, f->page_offset, f->size,
-                                    offset, len, skb, spd, 0, sk))
+                                    offset, len, skb, spd, 0, sk, pipe))
                        return 1;
        }
 
@@ -1520,8 +1526,8 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
                    struct pipe_inode_info *pipe, unsigned int tlen,
                    unsigned int flags)
 {
-       struct partial_page partial[PIPE_BUFFERS];
-       struct page *pages[PIPE_BUFFERS];
+       struct partial_page partial[PIPE_DEF_BUFFERS];
+       struct page *pages[PIPE_DEF_BUFFERS];
        struct splice_pipe_desc spd = {
                .pages = pages,
                .partial = partial,
@@ -1531,12 +1537,16 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
        };
        struct sk_buff *frag_iter;
        struct sock *sk = skb->sk;
+       int ret = 0;
+
+       if (splice_grow_spd(pipe, &spd))
+               return -ENOMEM;
 
        /*
         * __skb_splice_bits() only fails if the output has no room left,
         * so no point in going over the frag_list for the error case.
         */
-       if (__skb_splice_bits(skb, &offset, &tlen, &spd, sk))
+       if (__skb_splice_bits(skb, pipe, &offset, &tlen, &spd, sk))
                goto done;
        else if (!tlen)
                goto done;
@@ -1547,14 +1557,12 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
        skb_walk_frags(skb, frag_iter) {
                if (!tlen)
                        break;
-               if (__skb_splice_bits(frag_iter, &offset, &tlen, &spd, sk))
+               if (__skb_splice_bits(frag_iter, pipe, &offset, &tlen, &spd, sk))
                        break;
        }
 
 done:
        if (spd.nr_pages) {
-               int ret;
-
                /*
                 * Drop the socket lock, otherwise we have reverse
                 * locking dependencies between sk_lock and i_mutex
@@ -1567,10 +1575,10 @@ done:
                release_sock(sk);
                ret = splice_to_pipe(pipe, &spd);
                lock_sock(sk);
-               return ret;
        }
 
-       return 0;
+       splice_shrink_spd(pipe, &spd);
+       return ret;
 }
 
 /**
@@ -2689,7 +2697,8 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 
                NAPI_GRO_CB(skb)->free = 1;
                goto done;
-       }
+       } else if (skb_gro_len(p) != pinfo->gso_size)
+               return -E2BIG;
 
        headroom = skb_headroom(p);
        nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p));
@@ -2713,6 +2722,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
        *NAPI_GRO_CB(nskb) = *NAPI_GRO_CB(p);
        skb_shinfo(nskb)->frag_list = p;
        skb_shinfo(nskb)->gso_size = pinfo->gso_size;
+       pinfo->gso_size = 0;
        skb_header_release(p);
        nskb->prev = p;