From patchwork Thu Dec 16 05:57:25 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Changli Gao X-Patchwork-Id: 75721 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id A4B6F1007D6 for ; Thu, 16 Dec 2010 16:57:55 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751972Ab0LPF5v (ORCPT ); Thu, 16 Dec 2010 00:57:51 -0500 Received: from mail-pw0-f46.google.com ([209.85.160.46]:60489 "EHLO mail-pw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751886Ab0LPF5u (ORCPT ); Thu, 16 Dec 2010 00:57:50 -0500 Received: by pwj3 with SMTP id 3so370708pwj.19 for ; Wed, 15 Dec 2010 21:57:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer; bh=cc+X6AVBWzsQWPlgSUx2sH9boTRvRECKDW5oxNLRmws=; b=Adl/0Vqh9yn0vamLiWa1uCB7jbYgboXOxeL87Uv2MMfO7viUUVwttFMpH/UmLyTQm9 NFdrtrPg4YrBtO2DX+bN3hQETBEc4V+1zSNLtYwH7J7f6F/EgcUL26y4vUt4plsnfvua etoizbYZ/EZgV31Y+uhfBUw4DPnyyIwjlEzQU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=qUjasWmcZTYJBpPYTdbVV6wmHf/rO5MHW2RoAUb2YL6ra9DTgEbuLwpG5gr/t0KMNw XrrbEHLXpf1fUcl2kwg2pp4z7xXXkFlRmutjpn0zGNarYztGO0xq4Bca2bwUJESLuluQ cnLAAskzxDkVND+DIs+iTTiB+d+CjkHYs1nEc= Received: by 10.142.161.10 with SMTP id j10mr4844113wfe.195.1292479070076; Wed, 15 Dec 2010 21:57:50 -0800 (PST) Received: from localhost.localdomain ([221.239.34.230]) by mx.google.com with ESMTPS id w14sm2601348wfd.18.2010.12.15.21.57.39 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 15 Dec 2010 21:57:49 -0800 (PST) From: Changli Gao To: "David S. Miller" Cc: Eric Dumazet , Tom Herbert , Jiri Pirko , Fenghua Yu , Junchang Wang , Xinan Tang , netdev@vger.kernel.org, Changli Gao Subject: [PATCH] net: increase skb->users instead of skb_clone() Date: Thu, 16 Dec 2010 13:57:25 +0800 Message-Id: <1292479045-3136-1-git-send-email-xiaosuo@gmail.com> X-Mailer: git-send-email 1.7.1 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In dev_queue_xmit_nit(), we have to clone skbs as we need to mangle skbs, however, we don't need to clone skbs for all the packet_types. Except for the first packet_type, we increase skb->users instead of skb_clone(). Signed-off-by: Changli Gao Acked-by: Eric Dumazet --- net/core/dev.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 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/net/core/dev.c b/net/core/dev.c index bf5ced5..888cb74 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1496,6 +1496,14 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) } EXPORT_SYMBOL_GPL(dev_forward_skb); +static inline int deliver_skb(struct sk_buff *skb, + struct packet_type *pt_prev, + struct net_device *orig_dev) +{ + atomic_inc(&skb->users); + return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); +} + /* * Support routine. Sends outgoing frames to any network * taps currently in use. @@ -1504,6 +1512,8 @@ EXPORT_SYMBOL_GPL(dev_forward_skb); static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) { struct packet_type *ptype; + struct sk_buff *skb2 = NULL; + struct packet_type *pt_prev = NULL; #ifdef CONFIG_NET_CLS_ACT if (!(skb->tstamp.tv64 && (G_TC_FROM(skb->tc_verd) & AT_INGRESS))) @@ -1520,7 +1530,13 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) if ((ptype->dev == dev || !ptype->dev) && (ptype->af_packet_priv == NULL || (struct sock *)ptype->af_packet_priv != skb->sk)) { - struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); + if (pt_prev) { + deliver_skb(skb2, pt_prev, skb->dev); + pt_prev = ptype; + continue; + } + + skb2 = skb_clone(skb, GFP_ATOMIC); if (!skb2) break; @@ -1542,9 +1558,11 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) skb2->transport_header = skb2->network_header; skb2->pkt_type = PACKET_OUTGOING; - ptype->func(skb2, skb->dev, ptype, skb->dev); + pt_prev = ptype; } } + if (pt_prev) + pt_prev->func(skb2, skb->dev, pt_prev, skb->dev); rcu_read_unlock(); } @@ -2788,14 +2806,6 @@ static void net_tx_action(struct softirq_action *h) } } -static inline int deliver_skb(struct sk_buff *skb, - struct packet_type *pt_prev, - struct net_device *orig_dev) -{ - atomic_inc(&skb->users); - return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); -} - #if (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) && \ (defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)) /* This hook is defined here for ATM LANE */