From patchwork Wed May 27 04:50:27 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herbert Xu X-Patchwork-Id: 27700 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id 6BE95B6F35 for ; Wed, 27 May 2009 14:50:50 +1000 (EST) Received: by ozlabs.org (Postfix) id 5EC13DE03E; Wed, 27 May 2009 14:50:50 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 078B8DDFE8 for ; Wed, 27 May 2009 14:50:50 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753316AbZE0Eud (ORCPT ); Wed, 27 May 2009 00:50:33 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752606AbZE0Eud (ORCPT ); Wed, 27 May 2009 00:50:33 -0400 Received: from rhun.apana.org.au ([64.62.148.172]:37539 "EHLO arnor.apana.org.au" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752770AbZE0Eub (ORCPT ); Wed, 27 May 2009 00:50:31 -0400 Received: from gondolin.me.apana.org.au ([192.168.0.6]) by arnor.apana.org.au with esmtp (Exim 4.63 #1 (Debian)) id 1M9B5w-0004VP-V2; Wed, 27 May 2009 14:50:29 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 4.69) (envelope-from ) id 1M9B5v-0001SU-M7; Wed, 27 May 2009 14:50:27 +1000 Subject: [PATCH 8/14] gro: Optimise length comparison in skb_gro_header References: <20090527044539.GA32372@gondor.apana.org.au> To: "David S. Miller" , netdev@vger.kernel.org Message-Id: From: Herbert Xu Date: Wed, 27 May 2009 14:50:27 +1000 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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: Herbert Xu --- include/linux/netdevice.h | 7 +++++-- net/core/dev.c | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 38678bc..966c413 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1011,6 +1011,9 @@ struct napi_gro_cb { /* Virtual address of skb_shinfo(skb)->frags[0].page + offset. */ void *frag0; + /* Length of frag0. */ + unsigned int frag0_len; + /* This indicates where we are processing relative to skb->data. */ int data_offset; @@ -1134,9 +1137,9 @@ static inline void *skb_gro_header(struct sk_buff *skb, unsigned int hlen) unsigned int offset = skb_gro_offset(skb); hlen += offset; - if (!NAPI_GRO_CB(skb)->frag0 || - unlikely(skb_shinfo(skb)->frags[0].size < hlen)) { + if (NAPI_GRO_CB(skb)->frag0_len < hlen) { NAPI_GRO_CB(skb)->frag0 = NULL; + NAPI_GRO_CB(skb)->frag0_len = 0; return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; } diff --git a/net/core/dev.c b/net/core/dev.c index 07ad237..e634c8a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2506,12 +2506,15 @@ void skb_gro_reset_offset(struct sk_buff *skb) { NAPI_GRO_CB(skb)->data_offset = 0; NAPI_GRO_CB(skb)->frag0 = NULL; + NAPI_GRO_CB(skb)->frag0_len = 0; 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 = page_address(skb_shinfo(skb)->frags[0].page) + 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);