netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next-2.6] net: eth_type_trans() should inline skb_pull()
@ 2010-05-01  6:42 Eric Dumazet
  2010-05-02  1:15 ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: Eric Dumazet @ 2010-05-01  6:42 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Tom Herbert, jamal

840.000 pps instead of 800.000 pps on my 'old' machine, using RPS

Before patch, profile of CPU 0 (handling tg3 interrupts)

             2167.00 13.9% __alloc_skb            vmlinux
             1908.00 12.3% eth_type_trans         vmlinux
             1125.00  7.2% __kmalloc_track_caller vmlinux
              981.00  6.3% __netdev_alloc_skb     vmlinux
              925.00  5.9% _raw_spin_lock         vmlinux
              786.00  5.1% kmem_cache_alloc       vmlinux
              757.00  4.9% skb_pull               vmlinux
              698.00  4.5% tg3_read32             vmlinux
              637.00  4.1% __slab_alloc           vmlinux
              620.00  4.0% tg3_poll_work          vmlinux
              576.00  3.7% get_rps_cpu            vmlinux
              448.00  2.9% bnx2_interrupt         vmlinux

After (no more skb_pull, and eth_type_trans() not more expensive)
Predominant cost is memory allocator...

             1625.00 12.4% eth_type_trans         vmlinux
             1468.00 11.2% __alloc_skb            vmlinux
             1004.00  7.6% __kmalloc_track_caller vmlinux
              893.00  6.8% _raw_spin_lock         vmlinux
              738.00  5.6% __netdev_alloc_skb     vmlinux
              665.00  5.1% tg3_read32             vmlinux
              656.00  5.0% kmem_cache_alloc       vmlinux
              655.00  5.0% __slab_alloc           vmlinux
              509.00  3.9% bnx2_interrupt         vmlinux
              483.00  3.7% tg3_poll_work          vmlinux
              455.00  3.5% _raw_spin_lock_irqsave vmlinux
              330.00  2.5% get_rps_cpu            vmlinux
              286.00  2.2% nommu_map_page         vmlinux
              277.00  2.1% enqueue_to_backlog     vmlinux
              235.00  1.8% inet_gro_receive       vmlinux
              232.00  1.8% __copy_to_user_ll      vmlinux
              181.00  1.4% dev_gro_receive        vmlinux
              165.00  1.3% skb_gro_reset_offset   vmlinux

(bnx2_interrupt is called, because irq 16 is shared on this machine on two nics...)

Thanks !

[PATCH net-next-2.6] net: eth_type_trans() should inline skb_pull()

With RPS, this patch can give a 5 % boost in performance.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 0c0d272..763524b 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -162,7 +162,8 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
 
 	skb->dev = dev;
 	skb_reset_mac_header(skb);
-	skb_pull(skb, ETH_HLEN);
+	if (likely(skb->len >= ETH_HLEN))
+		__skb_pull(skb, ETH_HLEN);
 	eth = eth_hdr(skb);
 
 	if (unlikely(is_multicast_ether_addr(eth->h_dest))) {



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next-2.6] net: eth_type_trans() should inline skb_pull()
  2010-05-01  6:42 [PATCH net-next-2.6] net: eth_type_trans() should inline skb_pull() Eric Dumazet
@ 2010-05-02  1:15 ` David Miller
  2010-05-02  6:50   ` Eric Dumazet
  0 siblings, 1 reply; 4+ messages in thread
From: David Miller @ 2010-05-02  1:15 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, therbert, hadi

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sat, 01 May 2010 08:42:25 +0200

> [PATCH net-next-2.6] net: eth_type_trans() should inline skb_pull()
> 
> With RPS, this patch can give a 5 % boost in performance.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Awesome, but let's do this in a way that allows us to easily annotate
where inlining makes sense in other places, not just here.

Something like this, ok?

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 82f5116..746a652 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1128,6 +1128,11 @@ static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
 	return skb->data += len;
 }
 
+static inline unsigned char *skb_pull_inline(struct sk_buff *skb, unsigned int len)
+{
+	return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
+}
+
 extern unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta);
 
 static inline unsigned char *__pskb_pull(struct sk_buff *skb, unsigned int len)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4218ff4..8b9c109 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1051,7 +1051,7 @@ EXPORT_SYMBOL(skb_push);
  */
 unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
 {
-	return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
+	return skb_pull_inline(skb, len);
 }
 EXPORT_SYMBOL(skb_pull);
 
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 0c0d272..61ec032 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -162,7 +162,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
 
 	skb->dev = dev;
 	skb_reset_mac_header(skb);
-	skb_pull(skb, ETH_HLEN);
+	skb_pull_inline(skb, ETH_HLEN);
 	eth = eth_hdr(skb);
 
 	if (unlikely(is_multicast_ether_addr(eth->h_dest))) {

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next-2.6] net: eth_type_trans() should inline skb_pull()
  2010-05-02  1:15 ` David Miller
@ 2010-05-02  6:50   ` Eric Dumazet
  2010-05-02 10:03     ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: Eric Dumazet @ 2010-05-02  6:50 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, therbert, hadi

Le samedi 01 mai 2010 à 18:15 -0700, David Miller a écrit :
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Sat, 01 May 2010 08:42:25 +0200
> 
> > [PATCH net-next-2.6] net: eth_type_trans() should inline skb_pull()
> > 
> > With RPS, this patch can give a 5 % boost in performance.
> > 
> > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> 
> Awesome, but let's do this in a way that allows us to easily annotate
> where inlining makes sense in other places, not just here.
> 
> Something like this, ok?
> 
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index 82f5116..746a652 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -1128,6 +1128,11 @@ static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
>  	return skb->data += len;
>  }
>  
> +static inline unsigned char *skb_pull_inline(struct sk_buff *skb, unsigned int len)
> +{
> +	return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
> +}
> +
>  extern unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta);
>  
>  static inline unsigned char *__pskb_pull(struct sk_buff *skb, unsigned int len)
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 4218ff4..8b9c109 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -1051,7 +1051,7 @@ EXPORT_SYMBOL(skb_push);
>   */
>  unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
>  {
> -	return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
> +	return skb_pull_inline(skb, len);
>  }
>  EXPORT_SYMBOL(skb_pull);
>  
> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> index 0c0d272..61ec032 100644
> --- a/net/ethernet/eth.c
> +++ b/net/ethernet/eth.c
> @@ -162,7 +162,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
>  
>  	skb->dev = dev;
>  	skb_reset_mac_header(skb);
> -	skb_pull(skb, ETH_HLEN);
> +	skb_pull_inline(skb, ETH_HLEN);
>  	eth = eth_hdr(skb);
>  
>  	if (unlikely(is_multicast_ether_addr(eth->h_dest))) {

Excellent !

Changli privately asked me why we were ignoring cases where skb->len <
ETH_HLEN.
I replied that minimum frame size was 46+12, then he asked me why we
were testing another time :

if (skb->len >= 2 && *(unsigned short *)rawp == 0xFFFF)
	return htons(ETH_P_802_3);


Could we assume all eth_type_trans() must call it with initial skb->len
>= (46 + 12) or not ?
(According to ethernet specs, all frames should have a minimum payload
of 46 bytes)

If not sure, maybe we should issue a WARN_ON_ONCE()

If yes, tests could be removed and we could gain two cycles ;)




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next-2.6] net: eth_type_trans() should inline skb_pull()
  2010-05-02  6:50   ` Eric Dumazet
@ 2010-05-02 10:03     ` David Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2010-05-02 10:03 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, therbert, hadi

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 02 May 2010 08:50:32 +0200

> Excellent !

Great, here is the commit message I will use:

--------------------
net: Inline skb_pull() in eth_type_trans().

In commit 6be8ac2f ("[NET]: uninline skb_pull, de-bloats a lot")
we uninlined skb_pull.

But in some critical paths it makes sense to inline this thing
and it helps performance significantly.

Create an skb_pull_inline() so that we can do this in a way that
serves also as annotation.

Based upon a patch by Eric Dumazet.

Signed-off-by: David S. Miller <davem@davemloft.net>
--------------------

> Could we assume all eth_type_trans() must call it with initial
> skb->len >= (46 + 12) or not ?  (According to ethernet specs, all
> frames should have a minimum payload of 46 bytes)
>
> If not sure, maybe we should issue a WARN_ON_ONCE()
> 
> If yes, tests could be removed and we could gain two cycles ;)

Isn't the minimum ETH_ZLEN?

But yes, regardless of whether the minimum ethernet frame is 58 or 60
bytes, we should require it's at least that big, and use that test
consistently throughout.

Anything smaller is a runt packet and should be tossed or marked as an
error in some other way by the hardware.  They should never make it to
eth_type_trans().

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-05-02 10:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-01  6:42 [PATCH net-next-2.6] net: eth_type_trans() should inline skb_pull() Eric Dumazet
2010-05-02  1:15 ` David Miller
2010-05-02  6:50   ` Eric Dumazet
2010-05-02 10:03     ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).