From 7e7d587d68a22aa47745d5acadd9790d1a34934f Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Fri, 11 Jun 2010 15:10:35 -0700 Subject: [PATCH] gre: Improve headroom calculation to reducing copying. The first change is use skb_header_cloned() instead of (skb_cloned() && skb_clone_writable()). While these are effectively the same checks, skb_clone_writable() does not exist until 2.6.23 and relies on information not available in earlier kernels and therefore the compat version always returns false. Since GRE only adds data to the front of the packet and this is on the transmit path (meaning there is no important data in the SKB head) it is safe to use skb_header_cloned(). This avoids a copy for locally generated TCP packets on the affected kernels. The second change is to always allocate 64 bytes of headroom when a copy needs to be made. There is no cost to allocating extra space once we have decided to make a copy and can avoid another copy later if we need to add a VLAN tag. --- datapath/vport-gre.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c index cd0f3e8dc..98e0abc3b 100644 --- a/datapath/vport-gre.c +++ b/datapath/vport-gre.c @@ -557,9 +557,8 @@ send_frag_needed(struct vport *vport, const struct mutable_config *mutable, static struct sk_buff * check_headroom(struct sk_buff *skb, int headroom) { - if (skb_headroom(skb) < headroom || - (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { - struct sk_buff *nskb = skb_realloc_headroom(skb, headroom); + if (skb_headroom(skb) < headroom || skb_header_cloned(skb)) { + struct sk_buff *nskb = skb_realloc_headroom(skb, max(headroom, 64)); if (!nskb) { kfree_skb(skb); return ERR_PTR(-ENOMEM); -- 2.43.0