|
@@ -179,6 +179,33 @@ out:
|
|
|
*
|
|
|
*/
|
|
|
|
|
|
+struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node)
|
|
|
+{
|
|
|
+ struct sk_buff *skb;
|
|
|
+
|
|
|
+ /* Get the HEAD */
|
|
|
+ skb = kmem_cache_alloc_node(skbuff_head_cache,
|
|
|
+ gfp_mask & ~__GFP_DMA, node);
|
|
|
+ if (!skb)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Only clear those fields we need to clear, not those that we will
|
|
|
+ * actually initialise below. Hence, don't put any more fields after
|
|
|
+ * the tail pointer in struct sk_buff!
|
|
|
+ */
|
|
|
+ memset(skb, 0, offsetof(struct sk_buff, tail));
|
|
|
+ skb->data = NULL;
|
|
|
+ skb->truesize = sizeof(struct sk_buff);
|
|
|
+ atomic_set(&skb->users, 1);
|
|
|
+
|
|
|
+#ifdef NET_SKBUFF_DATA_USES_OFFSET
|
|
|
+ skb->mac_header = ~0U;
|
|
|
+#endif
|
|
|
+out:
|
|
|
+ return skb;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* __alloc_skb - allocate a network buffer
|
|
|
* @size: size to allocate
|
|
@@ -584,7 +611,8 @@ static void skb_release_head_state(struct sk_buff *skb)
|
|
|
static void skb_release_all(struct sk_buff *skb)
|
|
|
{
|
|
|
skb_release_head_state(skb);
|
|
|
- skb_release_data(skb);
|
|
|
+ if (likely(skb->data))
|
|
|
+ skb_release_data(skb);
|
|
|
}
|
|
|
|
|
|
/**
|