From: Jesse Gross Date: Wed, 8 Jun 2011 00:09:35 +0000 (-0700) Subject: tunneling: Avoid extra copying if expanding headroom. X-Git-Tag: v1.2.0~172 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=bf16ba4a9b1b4a38c867349e70e39d551b406b32;p=sliver-openvswitch.git tunneling: Avoid extra copying if expanding headroom. Currently if we need additional headroom before encapsulating a packet a clone is made before expanding headroom or if we are just trying to make the headroom writable then we copy both the struct sk_buff and the paged data. Both of these are unnecessary and we end up freeing the original copy. We can remove these copies and simplify the code by just expanding the linear data area. Signed-off-by: Jesse Gross Acked-by: Ben Pfaff --- diff --git a/datapath/tunnel.c b/datapath/tunnel.c index 326322336..2bf61597d 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -1027,27 +1027,6 @@ static struct rtable *find_route(struct vport *vport, } } -static struct sk_buff *check_headroom(struct sk_buff *skb, int headroom) -{ - if (skb_headroom(skb) < headroom || skb_header_cloned(skb)) { - struct sk_buff *nskb = skb_realloc_headroom(skb, headroom + 16); - if (unlikely(!nskb)) { - kfree_skb(skb); - return ERR_PTR(-ENOMEM); - } - - set_skb_csum_bits(skb, nskb); - - if (skb->sk) - skb_set_owner_w(nskb, skb->sk); - - kfree_skb(skb); - return nskb; - } - - return skb; -} - static inline bool need_linearize(const struct sk_buff *skb) { int i; @@ -1084,10 +1063,14 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb, + mutable->tunnel_hlen + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); - skb = check_headroom(skb, min_headroom); - if (IS_ERR(skb)) { - err = PTR_ERR(skb); - goto error; + if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) { + int head_delta = SKB_DATA_ALIGN(min_headroom - + skb_headroom(skb) + + 16); + err = pskb_expand_head(skb, max_t(int, head_delta, 0), + 0, GFP_ATOMIC); + if (unlikely(err)) + goto error_free; } if (skb_is_gso(skb)) {