From 33c1abbe284d50447e0247bc35a4e117640a2988 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 24 Aug 2004 03:03:36 -0700 Subject: [PATCH] [NET]: Use pskb_expand_head() instead of skb_copy() in skb_checksum_help(). Here is the patch that you wanted to shoot holes at :) The idea is simple. None of the callers of skb_checksum are passing it skb's which are shared. They may be cloned however. But the application checksum is always in the skb header so there is no need to linearise it. Supposing all these assumptions are correct, then we can avoid the overhead of skb_copy() and get away with pskb_expand_head(). If the assumption is wrong, we will find out because pskb_expand_head() will BUG() if skb_shared() is true. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/core/dev.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index da7fabc7aa26a..d8a5791a665f7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1144,16 +1144,10 @@ int skb_checksum_help(struct sk_buff **pskb, int inward) goto out; } - if (skb_shared(*pskb) || skb_cloned(*pskb)) { - struct sk_buff *newskb = skb_copy(*pskb, GFP_ATOMIC); - if (!newskb) { - ret = -ENOMEM; + if (skb_cloned(*pskb)) { + ret = pskb_expand_head(*pskb, 0, 0, GFP_ATOMIC); + if (ret) goto out; - } - if ((*pskb)->sk) - skb_set_owner_w(newskb, (*pskb)->sk); - kfree_skb(*pskb); - *pskb = newskb; } if (offset > (int)(*pskb)->len) -- 2.53.0