diff options
author | Eric Dumazet <dada1@cosmosbay.com> | 2009-05-01 09:05:06 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-01 09:05:06 -0700 |
commit | ec581f6a42bbbea5271c66da9769a41b46c74e10 (patch) | |
tree | 608636f6519789f3504fd4d0077568cc25d89b5a /net/core | |
parent | 7a67e56fd362d3edfde1f19170893508c3940d3a (diff) | |
download | op-kernel-dev-ec581f6a42bbbea5271c66da9769a41b46c74e10.zip op-kernel-dev-ec581f6a42bbbea5271c66da9769a41b46c74e10.tar.gz |
net: Fix skb_tx_hash() for forwarding workloads.
When skb_rx_queue_recorded() is true, we dont want to use jash distribution
as the device driver exactly told us which queue was selected at RX time.
jhash makes a statistical shuffle, but this wont work with 8 static inputs.
Later improvements would be to compute reciprocal value of real_num_tx_queues
to avoid a divide here. But this computation should be done once,
when real_num_tx_queues is set. This needs a separate patch, and a new
field in struct net_device.
Reported-by: Andrew Dickinson <andrew@whydna.net>
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 308a7d0..e2e9e4a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1735,11 +1735,12 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb) { u32 hash; - if (skb_rx_queue_recorded(skb)) { - hash = skb_get_rx_queue(skb); - } else if (skb->sk && skb->sk->sk_hash) { + if (skb_rx_queue_recorded(skb)) + return skb_get_rx_queue(skb) % dev->real_num_tx_queues; + + if (skb->sk && skb->sk->sk_hash) hash = skb->sk->sk_hash; - } else + else hash = skb->protocol; hash = jhash_1word(hash, skb_tx_hashrnd); |