Wireless: nl80211, fix lock imbalance
[firefly-linux-kernel-4.4.55.git] / net / core / skbuff.c
index 1a94a3037370a4c70ee3862fb9676a4975eddeb1..9e0597d189b0a35342b5b16e46186d8b19a4640e 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>
@@ -201,6 +202,12 @@ 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);
        atomic_set(&shinfo->dataref, 1);
@@ -217,6 +224,8 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
                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);
 
@@ -635,6 +644,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 +669,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 +852,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 +945,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;