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 <[email protected]> --- datapath/tunnel.c | 32 +++++++------------------------- 1 files changed, 7 insertions(+), 25 deletions(-) diff --git a/datapath/tunnel.c b/datapath/tunnel.c index 3263223..159583d 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,13 @@ 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)) { + err = pskb_expand_head(skb, max_t(int, + SKB_DATA_ALIGN(min_headroom - + skb_headroom(skb) + 16), 0), + 0, GFP_ATOMIC); + if (unlikely(err)) + goto error_free; } if (skb_is_gso(skb)) { -- 1.7.4.1 _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
