Message ID | 20090503.144418.255531526.davem@davemloft.net |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
David Miller a écrit : > From: David Miller <davem@davemloft.net> > Date: Fri, 01 May 2009 09:17:47 -0700 (PDT) > >> From: Eric Dumazet <dada1@cosmosbay.com> >> Date: Fri, 01 May 2009 11:29:54 +0200 >> >>> - } else if (skb->sk && skb->sk->sk_hash) { >>> + /* >>> + * Try to avoid an expensive divide, for symmetric setups : >>> + * number of tx queues of output device == >>> + * number of rx queues of incoming device >>> + */ >>> + if (hash >= dev->real_num_tx_queues) >>> + hash %= dev->real_num_tx_queues; >>> + return hash; >>> + } >> Subtraction in a while() loop is almost certainly a lot >> faster. > > To move forward on this, I've commited the following to > net-next-2.6, thanks! > > net: Avoid modulus in skb_tx_hash() for forwarding case. > > Based almost entirely upon a patch by Eric Dumazet. > > The common case is to have num-tx-queues <= num_rx_queues > and even if num_tx_queues is larger it will not be significantly > larger. > > Therefore, a subtraction loop is always going to be faster than > modulus. > > Signed-off-by: David S. Miller <davem@davemloft.net> > --- > net/core/dev.c | 8 ++++++-- > 1 files changed, 6 insertions(+), 2 deletions(-) > > diff --git a/net/core/dev.c b/net/core/dev.c > index 8144295..3c8073f 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -1735,8 +1735,12 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb) > { > u32 hash; > > - if (skb_rx_queue_recorded(skb)) > - return skb_get_rx_queue(skb) % dev->real_num_tx_queues; > + if (skb_rx_queue_recorded(skb)) { > + hash = skb_get_rx_queue(skb); > + while (unlikely (hash >= dev->real_num_tx_queues)) > + hash -= dev->real_num_tx_queues; > + return hash; > + } > > if (skb->sk && skb->sk->sk_hash) > hash = skb->sk->sk_hash; Yes, I checked that compiler did not use a divide instruction here (I remember it did on a similar loop in kernel, related to time) Thank you -- 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 8144295..3c8073f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1735,8 +1735,12 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb) { u32 hash; - if (skb_rx_queue_recorded(skb)) - return skb_get_rx_queue(skb) % dev->real_num_tx_queues; + if (skb_rx_queue_recorded(skb)) { + hash = skb_get_rx_queue(skb); + while (unlikely (hash >= dev->real_num_tx_queues)) + hash -= dev->real_num_tx_queues; + return hash; + } if (skb->sk && skb->sk->sk_hash) hash = skb->sk->sk_hash;