[azure] hv_netvsc: Exclude non-TCP port numbers from vRSS hashing
diff mbox

Message ID 1501013133-26889-2-git-send-email-marcelo.cerri@canonical.com
State New
Headers show

Commit Message

Marcelo Henrique Cerri July 25, 2017, 8:05 p.m. UTC
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>
---
 drivers/net/hyperv/netvsc_drv.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

Comments

Stefan Bader July 27, 2017, 2:43 p.m. UTC | #1
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 */
>
Kamal Mostafa July 27, 2017, 4:34 p.m. UTC | #2

Marcelo Henrique Cerri July 27, 2017, 5:32 p.m. UTC | #3
Acked-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>

Patch
diff mbox

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 */