netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] net: remove useless prefetch() call
@ 2009-03-20  8:32 Eric Dumazet
  2009-03-20  8:36 ` David Miller
  0 siblings, 1 reply; 7+ messages in thread
From: Eric Dumazet @ 2009-03-20  8:32 UTC (permalink / raw)
  To: David S. Miller; +Cc: Linux Netdev List

There is no point to use prefetch() call here.
start_xmit() is a function like others...

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>

diff --git a/net/core/dev.c b/net/core/dev.c
index c013031..c97e27d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1670,7 +1670,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
 	const struct net_device_ops *ops = dev->netdev_ops;
 	int rc;
 
-	prefetch(&dev->netdev_ops->ndo_start_xmit);
 	if (likely(!skb->next)) {
 		if (!list_empty(&ptype_all))
 			dev_queue_xmit_nit(skb, dev);

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

* Re: [PATCH] net: remove useless prefetch() call
  2009-03-20  8:32 [PATCH] net: remove useless prefetch() call Eric Dumazet
@ 2009-03-20  8:36 ` David Miller
  2009-03-20  9:44   ` [NET] net: reorder struct net_device_ops Eric Dumazet
  0 siblings, 1 reply; 7+ messages in thread
From: David Miller @ 2009-03-20  8:36 UTC (permalink / raw)
  To: dada1; +Cc: netdev

From: Eric Dumazet <dada1@cosmosbay.com>
Date: Fri, 20 Mar 2009 09:32:53 +0100

> There is no point to use prefetch() call here.
> start_xmit() is a function like others...
> 
> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>

Yes but the operation pointer might not be in the CPU
cache at this time?

And if it's not we can get it into the cpu whilst we do
other processing, such as the dev_queue_xmit_nit() stuff.

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

* [NET] net: reorder struct net_device_ops
  2009-03-20  8:36 ` David Miller
@ 2009-03-20  9:44   ` Eric Dumazet
  2009-03-20 10:07     ` [PATCH] net: remove useless prefetch() call Eric Dumazet
  2009-03-20 12:47     ` [NET] net: reorder struct net_device_ops Bjørn Mork
  0 siblings, 2 replies; 7+ messages in thread
From: Eric Dumazet @ 2009-03-20  9:44 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

David Miller a écrit :
> From: Eric Dumazet <dada1@cosmosbay.com>
> Date: Fri, 20 Mar 2009 09:32:53 +0100
> 
>> There is no point to use prefetch() call here.
>> start_xmit() is a function like others...
>>
>> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
> 
> Yes but the operation pointer might not be in the CPU
> cache at this time?
> 
> And if it's not we can get it into the cpu whilst we do
> other processing, such as the dev_queue_xmit_nit() stuff.

This slow down fast path, but we can find a compromise.

I saw a strange effect on oprofile because of this prefetch()
on a situation we call xxx.xxx times per second dev_hard_start_xmit()
(So this ought to be in CPU cache already)

prefetch() is *free* only if the address computation is fast too :)

Thank you

[NET] net: reorder struct net_device_ops

Moving ndo_start_xmit() field at first position in
struct net_device_ops reduce the assembly needed to compute
the prefetch() address.

There seems to be an issue here on some cpus as spotted by oprofile
in dev_hard_start_xmit()
(prefetch() has a dependancy on previous add instruction)

	mov    %eax,-0x14(%ebp) /* store ops */
	add    $0x10,%eax       /* compute &ops->ndo_start_xmit */
	prefetcht0 (%eax)       /* stall here */

After patch, no add instruction is needed anymore.

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index be3ebd7..e507c6e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -547,14 +547,14 @@ struct netdev_queue {
  */
 #define HAVE_NET_DEVICE_OPS
 struct net_device_ops {
-	int			(*ndo_init)(struct net_device *dev);
-	void			(*ndo_uninit)(struct net_device *dev);
-	int			(*ndo_open)(struct net_device *dev);
-	int			(*ndo_stop)(struct net_device *dev);
 	int			(*ndo_start_xmit) (struct sk_buff *skb,
 						   struct net_device *dev);
 	u16			(*ndo_select_queue)(struct net_device *dev,
 						    struct sk_buff *skb);
+	int			(*ndo_init)(struct net_device *dev);
+	void			(*ndo_uninit)(struct net_device *dev);
+	int			(*ndo_open)(struct net_device *dev);
+	int			(*ndo_stop)(struct net_device *dev);
 #define HAVE_CHANGE_RX_FLAGS
 	void			(*ndo_change_rx_flags)(struct net_device *dev,
 						       int flags);
diff --git a/net/core/dev.c b/net/core/dev.c
index c013031..2e5ebd0 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1670,7 +1670,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
 	const struct net_device_ops *ops = dev->netdev_ops;
 	int rc;
 
-	prefetch(&dev->netdev_ops->ndo_start_xmit);
+	prefetch(&ops->ndo_start_xmit);
 	if (likely(!skb->next)) {
 		if (!list_empty(&ptype_all))
 			dev_queue_xmit_nit(skb, dev);


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

* [PATCH] net: remove useless prefetch() call
  2009-03-20  9:44   ` [NET] net: reorder struct net_device_ops Eric Dumazet
@ 2009-03-20 10:07     ` Eric Dumazet
  2009-03-21 20:43       ` David Miller
  2009-03-20 12:47     ` [NET] net: reorder struct net_device_ops Bjørn Mork
  1 sibling, 1 reply; 7+ messages in thread
From: Eric Dumazet @ 2009-03-20 10:07 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Eric Dumazet a écrit :
> David Miller a écrit :
>> From: Eric Dumazet <dada1@cosmosbay.com>
>> Date: Fri, 20 Mar 2009 09:32:53 +0100
>>
>>> There is no point to use prefetch() call here.
>>> start_xmit() is a function like others...
>>>
>>> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
>> Yes but the operation pointer might not be in the CPU
>> cache at this time?
>>
>> And if it's not we can get it into the cpu whilst we do
>> other processing, such as the dev_queue_xmit_nit() stuff.
> 
> This slow down fast path, but we can find a compromise.
> 

Hmm.. it seems that ndo_select_queue is accessed right before
ndo_start_xmit - by dev_pick_tx()) - and they share same cache line,
so operation pointer is in CPU cache.

So first patch is OK, what about this updated Changelog ?

Thank you

[PATCH] net: remove useless prefetch() call

There is no gain using prefetch() in dev_hard_start_xmit(), since
we already had to read ops->ndo_select_queue pointer in dev_pick_tx(),
and both pointers are probably located in the same cache line.

This prefetch call slows down fast path because of a stall in address
computation.

diff --git a/net/core/dev.c b/net/core/dev.c
index c013031..c97e27d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1670,7 +1670,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
 	const struct net_device_ops *ops = dev->netdev_ops;
 	int rc;
 
-	prefetch(&dev->netdev_ops->ndo_start_xmit);
 	if (likely(!skb->next)) {
 		if (!list_empty(&ptype_all))
 			dev_queue_xmit_nit(skb, dev);


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

* Re: [NET] net: reorder struct net_device_ops
  2009-03-20  9:44   ` [NET] net: reorder struct net_device_ops Eric Dumazet
  2009-03-20 10:07     ` [PATCH] net: remove useless prefetch() call Eric Dumazet
@ 2009-03-20 12:47     ` Bjørn Mork
  2009-03-20 12:53       ` Eric Dumazet
  1 sibling, 1 reply; 7+ messages in thread
From: Bjørn Mork @ 2009-03-20 12:47 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev

Eric Dumazet <dada1@cosmosbay.com> writes:

> [NET] net: reorder struct net_device_ops
>
> Moving ndo_start_xmit() field at first position in
> struct net_device_ops reduce the assembly needed to compute
> the prefetch() address.

You can't do this while the compatibility code is still there.

from net/core/dev.c:register_netdevice() :

		/* This works only because net_device_ops and the
		   compatiablity structure are the same. */
		dev->netdev_ops = (void *) &(dev->init);


Bjørn

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

* Re: [NET] net: reorder struct net_device_ops
  2009-03-20 12:47     ` [NET] net: reorder struct net_device_ops Bjørn Mork
@ 2009-03-20 12:53       ` Eric Dumazet
  0 siblings, 0 replies; 7+ messages in thread
From: Eric Dumazet @ 2009-03-20 12:53 UTC (permalink / raw)
  To: Bjørn Mork; +Cc: David Miller, netdev

Bjørn Mork a écrit :
> Eric Dumazet <dada1@cosmosbay.com> writes:
> 
>> [NET] net: reorder struct net_device_ops
>>
>> Moving ndo_start_xmit() field at first position in
>> struct net_device_ops reduce the assembly needed to compute
>> the prefetch() address.
> 
> You can't do this while the compatibility code is still there.
> 
> from net/core/dev.c:register_netdevice() :
> 
> 		/* This works only because net_device_ops and the
> 		   compatiablity structure are the same. */
> 		dev->netdev_ops = (void *) &(dev->init);
> 
> 
> Bjørn

Nice catch !

Yes, very true, but I discarded this patch anyway, I wont correct this.

Thank you



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

* Re: [PATCH] net: remove useless prefetch() call
  2009-03-20 10:07     ` [PATCH] net: remove useless prefetch() call Eric Dumazet
@ 2009-03-21 20:43       ` David Miller
  0 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2009-03-21 20:43 UTC (permalink / raw)
  To: dada1; +Cc: netdev

From: Eric Dumazet <dada1@cosmosbay.com>
Date: Fri, 20 Mar 2009 11:07:33 +0100

> So first patch is OK, what about this updated Changelog ?
> 
> [PATCH] net: remove useless prefetch() call
> 
> There is no gain using prefetch() in dev_hard_start_xmit(), since
> we already had to read ops->ndo_select_queue pointer in dev_pick_tx(),
> and both pointers are probably located in the same cache line.
> 
> This prefetch call slows down fast path because of a stall in address
> computation.

Applied, thanks.

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

end of thread, other threads:[~2009-03-21 20:43 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-20  8:32 [PATCH] net: remove useless prefetch() call Eric Dumazet
2009-03-20  8:36 ` David Miller
2009-03-20  9:44   ` [NET] net: reorder struct net_device_ops Eric Dumazet
2009-03-20 10:07     ` [PATCH] net: remove useless prefetch() call Eric Dumazet
2009-03-21 20:43       ` David Miller
2009-03-20 12:47     ` [NET] net: reorder struct net_device_ops Bjørn Mork
2009-03-20 12:53       ` Eric Dumazet

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).