diff options
author | Eric Dumazet <edumazet@google.com> | 2017-10-04 13:48:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-10-04 14:34:14 -0400 |
commit | c818fa9e288be5be7e360c33cf4f5e30f9fa206e (patch) | |
tree | 2d2bec98e7a84c3c1dd1a4a677381bb18dc3f06a | |
parent | e9b871ee098dfb91780e13bfc6e91e82c7b4ad73 (diff) |
net: cache skb_shinfo() in skb_try_coalesce()
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>
-rw-r--r-- | net/core/skbuff.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d98c2e3ce2bf..822a90e56aea 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -4767,6 +4767,7 @@ EXPORT_SYMBOL(kfree_skb_partial); | |||
4767 | bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, | 4767 | bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, |
4768 | bool *fragstolen, int *delta_truesize) | 4768 | bool *fragstolen, int *delta_truesize) |
4769 | { | 4769 | { |
4770 | struct skb_shared_info *to_shinfo, *from_shinfo; | ||
4770 | int i, delta, len = from->len; | 4771 | int i, delta, len = from->len; |
4771 | 4772 | ||
4772 | *fragstolen = false; | 4773 | *fragstolen = false; |
@@ -4781,7 +4782,9 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, | |||
4781 | return true; | 4782 | return true; |
4782 | } | 4783 | } |
4783 | 4784 | ||
4784 | if (skb_has_frag_list(to) || skb_has_frag_list(from)) | 4785 | to_shinfo = skb_shinfo(to); |
4786 | from_shinfo = skb_shinfo(from); | ||
4787 | if (to_shinfo->frag_list || from_shinfo->frag_list) | ||
4785 | return false; | 4788 | return false; |
4786 | if (skb_zcopy(to) || skb_zcopy(from)) | 4789 | if (skb_zcopy(to) || skb_zcopy(from)) |
4787 | return false; | 4790 | return false; |
@@ -4790,8 +4793,8 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, | |||
4790 | struct page *page; | 4793 | struct page *page; |
4791 | unsigned int offset; | 4794 | unsigned int offset; |
4792 | 4795 | ||
4793 | if (skb_shinfo(to)->nr_frags + | 4796 | if (to_shinfo->nr_frags + |
4794 | skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS) | 4797 | from_shinfo->nr_frags >= MAX_SKB_FRAGS) |
4795 | return false; | 4798 | return false; |
4796 | 4799 | ||
4797 | if (skb_head_is_locked(from)) | 4800 | if (skb_head_is_locked(from)) |
@@ -4802,12 +4805,12 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, | |||
4802 | page = virt_to_head_page(from->head); | 4805 | page = virt_to_head_page(from->head); |
4803 | offset = from->data - (unsigned char *)page_address(page); | 4806 | offset = from->data - (unsigned char *)page_address(page); |
4804 | 4807 | ||
4805 | skb_fill_page_desc(to, skb_shinfo(to)->nr_frags, | 4808 | skb_fill_page_desc(to, to_shinfo->nr_frags, |
4806 | page, offset, skb_headlen(from)); | 4809 | page, offset, skb_headlen(from)); |
4807 | *fragstolen = true; | 4810 | *fragstolen = true; |
4808 | } else { | 4811 | } else { |
4809 | if (skb_shinfo(to)->nr_frags + | 4812 | if (to_shinfo->nr_frags + |
4810 | skb_shinfo(from)->nr_frags > MAX_SKB_FRAGS) | 4813 | from_shinfo->nr_frags > MAX_SKB_FRAGS) |
4811 | return false; | 4814 | return false; |
4812 | 4815 | ||
4813 | delta = from->truesize - SKB_TRUESIZE(skb_end_offset(from)); | 4816 | 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, | |||
4815 | 4818 | ||
4816 | WARN_ON_ONCE(delta < len); | 4819 | WARN_ON_ONCE(delta < len); |
4817 | 4820 | ||
4818 | memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags, | 4821 | memcpy(to_shinfo->frags + to_shinfo->nr_frags, |
4819 | skb_shinfo(from)->frags, | 4822 | from_shinfo->frags, |
4820 | skb_shinfo(from)->nr_frags * sizeof(skb_frag_t)); | 4823 | from_shinfo->nr_frags * sizeof(skb_frag_t)); |
4821 | skb_shinfo(to)->nr_frags += skb_shinfo(from)->nr_frags; | 4824 | to_shinfo->nr_frags += from_shinfo->nr_frags; |
4822 | 4825 | ||
4823 | if (!skb_cloned(from)) | 4826 | if (!skb_cloned(from)) |
4824 | skb_shinfo(from)->nr_frags = 0; | 4827 | from_shinfo->nr_frags = 0; |
4825 | 4828 | ||
4826 | /* if the skb is not cloned this does nothing | 4829 | /* if the skb is not cloned this does nothing |
4827 | * since we set nr_frags to 0. | 4830 | * since we set nr_frags to 0. |
4828 | */ | 4831 | */ |
4829 | for (i = 0; i < skb_shinfo(from)->nr_frags; i++) | 4832 | for (i = 0; i < from_shinfo->nr_frags; i++) |
4830 | skb_frag_ref(from, i); | 4833 | __skb_frag_ref(&from_shinfo->frags[i]); |
4831 | 4834 | ||
4832 | to->truesize += delta; | 4835 | to->truesize += delta; |
4833 | to->len += len; | 4836 | to->len += len; |