]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
net: cache skb_shinfo() in skb_try_coalesce()
authorEric Dumazet <edumazet@google.com>
Wed, 4 Oct 2017 17:48:35 +0000 (10:48 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 4 Oct 2017 18:34:14 +0000 (11:34 -0700)
Compiler does not really know that skb_shinfo(to|from) are constants
in skb_try_coalesce(), lets cache their values to shrink code.

We might even take care of skb_zcopy() calls later.

$ size net/core/skbuff.o.before net/core/skbuff.o
   text    data     bss     dec     hex filename
  40727    1298       0   42025    a429 net/core/skbuff.o.before
  40631    1298       0   41929    a3c9 net/core/skbuff.o

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/skbuff.c

index d98c2e3ce2bfd9549647d6914b69cecd840de480..822a90e56aea2078a11d5361a2b2595812291274 100644 (file)
@@ -4767,6 +4767,7 @@ EXPORT_SYMBOL(kfree_skb_partial);
 bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
                      bool *fragstolen, int *delta_truesize)
 {
+       struct skb_shared_info *to_shinfo, *from_shinfo;
        int i, delta, len = from->len;
 
        *fragstolen = false;
@@ -4781,7 +4782,9 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
                return true;
        }
 
-       if (skb_has_frag_list(to) || skb_has_frag_list(from))
+       to_shinfo = skb_shinfo(to);
+       from_shinfo = skb_shinfo(from);
+       if (to_shinfo->frag_list || from_shinfo->frag_list)
                return false;
        if (skb_zcopy(to) || skb_zcopy(from))
                return false;
@@ -4790,8 +4793,8 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
                struct page *page;
                unsigned int offset;
 
-               if (skb_shinfo(to)->nr_frags +
-                   skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS)
+               if (to_shinfo->nr_frags +
+                   from_shinfo->nr_frags >= MAX_SKB_FRAGS)
                        return false;
 
                if (skb_head_is_locked(from))
@@ -4802,12 +4805,12 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
                page = virt_to_head_page(from->head);
                offset = from->data - (unsigned char *)page_address(page);
 
-               skb_fill_page_desc(to, skb_shinfo(to)->nr_frags,
+               skb_fill_page_desc(to, to_shinfo->nr_frags,
                                   page, offset, skb_headlen(from));
                *fragstolen = true;
        } else {
-               if (skb_shinfo(to)->nr_frags +
-                   skb_shinfo(from)->nr_frags > MAX_SKB_FRAGS)
+               if (to_shinfo->nr_frags +
+                   from_shinfo->nr_frags > MAX_SKB_FRAGS)
                        return false;
 
                delta = from->truesize - SKB_TRUESIZE(skb_end_offset(from));
@@ -4815,19 +4818,19 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
 
        WARN_ON_ONCE(delta < len);
 
-       memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags,
-              skb_shinfo(from)->frags,
-              skb_shinfo(from)->nr_frags * sizeof(skb_frag_t));
-       skb_shinfo(to)->nr_frags += skb_shinfo(from)->nr_frags;
+       memcpy(to_shinfo->frags + to_shinfo->nr_frags,
+              from_shinfo->frags,
+              from_shinfo->nr_frags * sizeof(skb_frag_t));
+       to_shinfo->nr_frags += from_shinfo->nr_frags;
 
        if (!skb_cloned(from))
-               skb_shinfo(from)->nr_frags = 0;
+               from_shinfo->nr_frags = 0;
 
        /* if the skb is not cloned this does nothing
         * since we set nr_frags to 0.
         */
-       for (i = 0; i < skb_shinfo(from)->nr_frags; i++)
-               skb_frag_ref(from, i);
+       for (i = 0; i < from_shinfo->nr_frags; i++)
+               __skb_frag_ref(&from_shinfo->frags[i]);
 
        to->truesize += delta;
        to->len += len;