Message ID | 1501013133-26889-2-git-send-email-marcelo.cerri@canonical.com |
---|---|
State | New |
Headers | show |
On 25.07.2017 22:05, Marcelo Henrique Cerri wrote: > From: Haiyang Zhang <haiyangz@microsoft.com> > > BugLink: http://bugs.launchpad.net/bugs/1690174 > > Azure hosts are not supporting non-TCP port numbers in vRSS hashing for > now. For example, UDP packet loss rate will be high if port numbers are > also included in vRSS hash. > > So, we created this patch to use only IP numbers for hashing in non-TCP > traffic. > > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> > Reviewed-by: Stephen Hemminger <sthemmin@microsoft.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (cherry picked from commit f72860afa2e32cdc674cbdd7f354f8fb62e908a6) > Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> > --- > drivers/net/hyperv/netvsc_drv.c | 32 +++++++++++++++++++++++++++++++- > 1 file changed, 31 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c > index 68a9b8bf5eb6..43b838c863cb 100644 > --- a/drivers/net/hyperv/netvsc_drv.c > +++ b/drivers/net/hyperv/netvsc_drv.c > @@ -191,6 +191,36 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size, > return ppi; > } > > +/* Azure hosts don't support non-TCP port numbers in hashing yet. We compute > + * hash for non-TCP traffic with only IP numbers. > + */ > +static inline u32 netvsc_get_hash(struct sk_buff *skb, struct sock *sk) > +{ > + struct flow_keys flow; > + u32 hash; > + static u32 hashrnd __read_mostly; > + > + net_get_random_once(&hashrnd, sizeof(hashrnd)); > + > + if (!skb_flow_dissect_flow_keys(skb, &flow, 0)) > + return 0; > + > + if (flow.basic.ip_proto == IPPROTO_TCP) { > + return skb_get_hash(skb); > + } else { > + if (flow.basic.n_proto == htons(ETH_P_IP)) > + hash = jhash2((u32 *)&flow.addrs.v4addrs, 2, hashrnd); > + else if (flow.basic.n_proto == htons(ETH_P_IPV6)) > + hash = jhash2((u32 *)&flow.addrs.v6addrs, 8, hashrnd); > + else > + hash = 0; > + > + skb_set_hash(skb, hash, PKT_HASH_TYPE_L3); > + } > + > + return hash; > +} > + > static inline int netvsc_get_tx_queue(struct net_device *ndev, > struct sk_buff *skb, int old_idx) > { > @@ -198,7 +228,7 @@ static inline int netvsc_get_tx_queue(struct net_device *ndev, > struct sock *sk = skb->sk; > int q_idx; > > - q_idx = ndc->tx_send_table[skb_get_hash(skb) & > + q_idx = ndc->tx_send_table[netvsc_get_hash(skb, sk) & > (VRSS_SEND_TAB_SIZE - 1)]; > > /* If queue index changed record the new value */ >
Acked-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 68a9b8bf5eb6..43b838c863cb 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -191,6 +191,36 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size, return ppi; } +/* Azure hosts don't support non-TCP port numbers in hashing yet. We compute + * hash for non-TCP traffic with only IP numbers. + */ +static inline u32 netvsc_get_hash(struct sk_buff *skb, struct sock *sk) +{ + struct flow_keys flow; + u32 hash; + static u32 hashrnd __read_mostly; + + net_get_random_once(&hashrnd, sizeof(hashrnd)); + + if (!skb_flow_dissect_flow_keys(skb, &flow, 0)) + return 0; + + if (flow.basic.ip_proto == IPPROTO_TCP) { + return skb_get_hash(skb); + } else { + if (flow.basic.n_proto == htons(ETH_P_IP)) + hash = jhash2((u32 *)&flow.addrs.v4addrs, 2, hashrnd); + else if (flow.basic.n_proto == htons(ETH_P_IPV6)) + hash = jhash2((u32 *)&flow.addrs.v6addrs, 8, hashrnd); + else + hash = 0; + + skb_set_hash(skb, hash, PKT_HASH_TYPE_L3); + } + + return hash; +} + static inline int netvsc_get_tx_queue(struct net_device *ndev, struct sk_buff *skb, int old_idx) { @@ -198,7 +228,7 @@ static inline int netvsc_get_tx_queue(struct net_device *ndev, struct sock *sk = skb->sk; int q_idx; - q_idx = ndc->tx_send_table[skb_get_hash(skb) & + q_idx = ndc->tx_send_table[netvsc_get_hash(skb, sk) & (VRSS_SEND_TAB_SIZE - 1)]; /* If queue index changed record the new value */