Message ID | 20170809124119.24320-5-john@phrozen.org |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
On Wed, Aug 09, 2017 at 02:41:19PM +0200, John Crispin wrote: > RPS and probably other kernel features are currently broken on some if not > all DSA devices. The root cause of this is that skb_hash will call the > flow_dissector. At this point the skb still contains the magic switch > header and the skb->protocol field is not set up to the correct 802.3 > value yet. By the time the tag specific code is called, removing the header > and properly setting the protocol an invalid hash is already set. In the > case of the mt7530 this will result in all flows always having the same > hash. > > Signed-off-by: Muciri Gatimu <muciri@openmesh.com> > Signed-off-by: Shashidhar Lakkavalli <shashidhar.lakkavalli@openmesh.com> > Signed-off-by: John Crispin <john@phrozen.org> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Andrew
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 0cc672aba1f0..5b5be9577257 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -4,6 +4,7 @@ #include <linux/ip.h> #include <linux/ipv6.h> #include <linux/if_vlan.h> +#include <net/dsa.h> #include <net/ip.h> #include <net/ipv6.h> #include <net/gre.h> @@ -440,6 +441,17 @@ bool __skb_flow_dissect(const struct sk_buff *skb, skb->vlan_proto : skb->protocol; nhoff = skb_network_offset(skb); hlen = skb_headlen(skb); + if (unlikely(netdev_uses_dsa(skb->dev))) { + const struct dsa_device_ops *ops; + int offset; + + ops = skb->dev->dsa_ptr->tag_ops; + if (ops->flow_dissect && + !ops->flow_dissect(skb, &proto, &offset)) { + hlen -= offset; + nhoff += offset; + } + } } /* It is ensured by skb_flow_dissector_init() that control key will