Commit 7489594c authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

gro: Optimise length comparison in skb_gro_header

By caching frag0_len, we can avoid checking both frag0 and the
length separately in skb_gro_header.  This helps as skb_gro_header
is called four times per packet which amounts to a few million
times at 10Gb/s.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 30a3ae30
...@@ -1011,6 +1011,9 @@ struct napi_gro_cb { ...@@ -1011,6 +1011,9 @@ struct napi_gro_cb {
/* Virtual address of skb_shinfo(skb)->frags[0].page + offset. */ /* Virtual address of skb_shinfo(skb)->frags[0].page + offset. */
void *frag0; void *frag0;
/* Length of frag0. */
unsigned int frag0_len;
/* This indicates where we are processing relative to skb->data. */ /* This indicates where we are processing relative to skb->data. */
int data_offset; int data_offset;
...@@ -1134,9 +1137,9 @@ static inline void *skb_gro_header(struct sk_buff *skb, unsigned int hlen) ...@@ -1134,9 +1137,9 @@ static inline void *skb_gro_header(struct sk_buff *skb, unsigned int hlen)
unsigned int offset = skb_gro_offset(skb); unsigned int offset = skb_gro_offset(skb);
hlen += offset; hlen += offset;
if (!NAPI_GRO_CB(skb)->frag0 || if (NAPI_GRO_CB(skb)->frag0_len < hlen) {
unlikely(skb_shinfo(skb)->frags[0].size < hlen)) {
NAPI_GRO_CB(skb)->frag0 = NULL; NAPI_GRO_CB(skb)->frag0 = NULL;
NAPI_GRO_CB(skb)->frag0_len = 0;
return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL;
} }
......
...@@ -2509,12 +2509,15 @@ void skb_gro_reset_offset(struct sk_buff *skb) ...@@ -2509,12 +2509,15 @@ void skb_gro_reset_offset(struct sk_buff *skb)
{ {
NAPI_GRO_CB(skb)->data_offset = 0; NAPI_GRO_CB(skb)->data_offset = 0;
NAPI_GRO_CB(skb)->frag0 = NULL; NAPI_GRO_CB(skb)->frag0 = NULL;
NAPI_GRO_CB(skb)->frag0_len = 0;
if (skb->mac_header == skb->tail && if (skb->mac_header == skb->tail &&
!PageHighMem(skb_shinfo(skb)->frags[0].page)) !PageHighMem(skb_shinfo(skb)->frags[0].page)) {
NAPI_GRO_CB(skb)->frag0 = NAPI_GRO_CB(skb)->frag0 =
page_address(skb_shinfo(skb)->frags[0].page) + page_address(skb_shinfo(skb)->frags[0].page) +
skb_shinfo(skb)->frags[0].page_offset; skb_shinfo(skb)->frags[0].page_offset;
NAPI_GRO_CB(skb)->frag0_len = skb_shinfo(skb)->frags[0].size;
}
} }
EXPORT_SYMBOL(skb_gro_reset_offset); EXPORT_SYMBOL(skb_gro_reset_offset);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment