aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/skbuff.h
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2016-04-30 10:19:29 -0700
committerDavid S. Miller <davem@davemloft.net>2016-05-03 00:22:19 -0400
commit9580bf2edb402b3afaf9c5a4efb6953f993ef52e (patch)
treeead375015918eb32b6ad7cb73a00a5567b8378ed /include/linux/skbuff.h
parentnetdevice: shrink size of struct netdev_queue (diff)
downloadlinux-dev-9580bf2edb402b3afaf9c5a4efb6953f993ef52e.tar.xz
linux-dev-9580bf2edb402b3afaf9c5a4efb6953f993ef52e.zip
net: relax expensive skb_unclone() in iptunnel_handle_offloads()
Locally generated TCP GSO packets having to go through a GRE/SIT/IPIP tunnel have to go through an expensive skb_unclone() Reallocating skb->head is a lot of work. Test should really check if a 'real clone' of the packet was done. TCP does not care if the original gso_type is changed while the packet travels in the stack. This adds skb_header_unclone() which is a variant of skb_clone() using skb_header_cloned() check instead of skb_cloned(). This variant can probably be used from other points. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/skbuff.h')
-rw-r--r--include/linux/skbuff.h10
1 files changed, 10 insertions, 0 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c84a5a1078c5..c413c588a24f 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1325,6 +1325,16 @@ static inline int skb_header_cloned(const struct sk_buff *skb)
return dataref != 1;
}
+static inline int skb_header_unclone(struct sk_buff *skb, gfp_t pri)
+{
+ might_sleep_if(gfpflags_allow_blocking(pri));
+
+ if (skb_header_cloned(skb))
+ return pskb_expand_head(skb, 0, 0, pri);
+
+ return 0;
+}
+
/**
* skb_header_release - release reference to header
* @skb: buffer to operate on