Commit ad55dcaf authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller

netdev: simple_tx_hash shouldn't hash inside fragments

Currently simple_tx_hash is hashing inside of udp fragments.  As a result
packets are getting getting sent to all queues when they shouldn't be.
This causes a serious performance regression which can be seen by sending
UDP frames larger than mtu on multiqueue devices.  This change will make
it so that fragments are hashed only as IP datagrams w/o any protocol
information.
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e7272403
...@@ -122,6 +122,7 @@ ...@@ -122,6 +122,7 @@
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <net/ip.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/jhash.h> #include <linux/jhash.h>
...@@ -1667,7 +1668,7 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb) ...@@ -1667,7 +1668,7 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
{ {
u32 addr1, addr2, ports; u32 addr1, addr2, ports;
u32 hash, ihl; u32 hash, ihl;
u8 ip_proto; u8 ip_proto = 0;
if (unlikely(!simple_tx_hashrnd_initialized)) { if (unlikely(!simple_tx_hashrnd_initialized)) {
get_random_bytes(&simple_tx_hashrnd, 4); get_random_bytes(&simple_tx_hashrnd, 4);
...@@ -1676,6 +1677,7 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb) ...@@ -1676,6 +1677,7 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
switch (skb->protocol) { switch (skb->protocol) {
case __constant_htons(ETH_P_IP): case __constant_htons(ETH_P_IP):
if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)))
ip_proto = ip_hdr(skb)->protocol; ip_proto = ip_hdr(skb)->protocol;
addr1 = ip_hdr(skb)->saddr; addr1 = ip_hdr(skb)->saddr;
addr2 = ip_hdr(skb)->daddr; addr2 = ip_hdr(skb)->daddr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment