All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next,0/3] hv_netvsc: support changing TCP hash level
@ 2017-10-06 15:33 Haiyang Zhang
  2017-10-06 15:33 ` [PATCH net-next,1/3] hv_netvsc: Change the hash level variable to bit flags Haiyang Zhang
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Haiyang Zhang @ 2017-10-06 15:33 UTC (permalink / raw)
  To: davem, netdev; +Cc: haiyangz, kys, sthemmin, olaf, vkuznets, linux-kernel

From: Haiyang Zhang <haiyangz@microsoft.com>

The patch set simplifies the existing hash level switching code for
UDP. It also adds the support for changing TCP hash level. So users
can switch between L3 an L4 hash levels for TCP and UDP.

Haiyang Zhang (3):
  hv_netvsc: Change the hash level variable to bit flags
  hv_netvsc: Add ethtool handler to set and get TCP hash levels
  hv_netvsc: Update netvsc Document for TCP hash level setting

 Documentation/networking/netvsc.txt |  8 ++--
 drivers/net/hyperv/hyperv_net.h     | 11 ++++-
 drivers/net/hyperv/netvsc_drv.c     | 96 ++++++++++++++++++++++++++++---------
 3 files changed, 86 insertions(+), 29 deletions(-)

-- 
2.14.1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH net-next,1/3] hv_netvsc: Change the hash level variable to bit flags
  2017-10-06 15:33 [PATCH net-next,0/3] hv_netvsc: support changing TCP hash level Haiyang Zhang
@ 2017-10-06 15:33 ` Haiyang Zhang
  2017-10-06 15:33 ` [PATCH net-next,2/3] hv_netvsc: Add ethtool handler to set and get TCP hash levels Haiyang Zhang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Haiyang Zhang @ 2017-10-06 15:33 UTC (permalink / raw)
  To: davem, netdev; +Cc: haiyangz, kys, sthemmin, olaf, vkuznets, linux-kernel

From: Haiyang Zhang <haiyangz@microsoft.com>

This simplifies the logic and make it easier to add more
options.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/net/hyperv/hyperv_net.h | 11 +++++--
 drivers/net/hyperv/netvsc_drv.c | 73 ++++++++++++++++++++++++++++-------------
 2 files changed, 59 insertions(+), 25 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 6f550e15a41c..a81335e8ebe8 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -704,6 +704,14 @@ struct netvsc_reconfig {
 	u32 event;
 };
 
+/* L4 hash bits for different protocols */
+#define HV_TCP4_L4HASH 1
+#define HV_TCP6_L4HASH 2
+#define HV_UDP4_L4HASH 4
+#define HV_UDP6_L4HASH 8
+#define HV_DEFAULT_L4HASH (HV_TCP4_L4HASH | HV_TCP6_L4HASH | HV_UDP4_L4HASH | \
+			   HV_UDP6_L4HASH)
+
 /* The context of the netvsc device  */
 struct net_device_context {
 	/* point back to our device context */
@@ -726,10 +734,9 @@ struct net_device_context {
 	u32 tx_send_table[VRSS_SEND_TAB_SIZE];
 
 	/* Ethtool settings */
-	bool udp4_l4_hash;
-	bool udp6_l4_hash;
 	u8 duplex;
 	u32 speed;
+	u32 l4_hash; /* L4 hash settings */
 	struct netvsc_ethtool_stats eth_stats;
 
 	/* State to manage the associated VF interface. */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index dfb986421ec6..9bc7dbab9506 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -203,7 +203,7 @@ static inline u32 netvsc_get_hash(
 	const struct net_device_context *ndc)
 {
 	struct flow_keys flow;
-	u32 hash;
+	u32 hash, pkt_proto = 0;
 	static u32 hashrnd __read_mostly;
 
 	net_get_random_once(&hashrnd, sizeof(hashrnd));
@@ -211,11 +211,25 @@ static inline u32 netvsc_get_hash(
 	if (!skb_flow_dissect_flow_keys(skb, &flow, 0))
 		return 0;
 
-	if (flow.basic.ip_proto == IPPROTO_TCP ||
-	    (flow.basic.ip_proto == IPPROTO_UDP &&
-	     ((flow.basic.n_proto == htons(ETH_P_IP) && ndc->udp4_l4_hash) ||
-	      (flow.basic.n_proto == htons(ETH_P_IPV6) &&
-	       ndc->udp6_l4_hash)))) {
+	switch (flow.basic.ip_proto) {
+	case IPPROTO_TCP:
+		if (flow.basic.n_proto == htons(ETH_P_IP))
+			pkt_proto = HV_TCP4_L4HASH;
+		else if (flow.basic.n_proto == htons(ETH_P_IPV6))
+			pkt_proto = HV_TCP6_L4HASH;
+
+		break;
+
+	case IPPROTO_UDP:
+		if (flow.basic.n_proto == htons(ETH_P_IP))
+			pkt_proto = HV_UDP4_L4HASH;
+		else if (flow.basic.n_proto == htons(ETH_P_IPV6))
+			pkt_proto = HV_UDP6_L4HASH;
+
+		break;
+	}
+
+	if (pkt_proto & ndc->l4_hash) {
 		return skb_get_hash(skb);
 	} else {
 		if (flow.basic.n_proto == htons(ETH_P_IP))
@@ -898,8 +912,7 @@ static void netvsc_init_settings(struct net_device *dev)
 {
 	struct net_device_context *ndc = netdev_priv(dev);
 
-	ndc->udp4_l4_hash = true;
-	ndc->udp6_l4_hash = true;
+	ndc->l4_hash = HV_DEFAULT_L4HASH;
 
 	ndc->speed = SPEED_UNKNOWN;
 	ndc->duplex = DUPLEX_FULL;
@@ -1245,23 +1258,25 @@ static int
 netvsc_get_rss_hash_opts(struct net_device_context *ndc,
 			 struct ethtool_rxnfc *info)
 {
+	const u32 l4_flag = RXH_L4_B_0_1 | RXH_L4_B_2_3;
+
 	info->data = RXH_IP_SRC | RXH_IP_DST;
 
 	switch (info->flow_type) {
 	case TCP_V4_FLOW:
 	case TCP_V6_FLOW:
-		info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		info->data |= l4_flag;
 		break;
 
 	case UDP_V4_FLOW:
-		if (ndc->udp4_l4_hash)
-			info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		if (ndc->l4_hash & HV_UDP4_L4HASH)
+			info->data |= l4_flag;
 
 		break;
 
 	case UDP_V6_FLOW:
-		if (ndc->udp6_l4_hash)
-			info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		if (ndc->l4_hash & HV_UDP6_L4HASH)
+			info->data |= l4_flag;
 
 		break;
 
@@ -1302,23 +1317,35 @@ static int netvsc_set_rss_hash_opts(struct net_device_context *ndc,
 {
 	if (info->data == (RXH_IP_SRC | RXH_IP_DST |
 			   RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
-		if (info->flow_type == UDP_V4_FLOW)
-			ndc->udp4_l4_hash = true;
-		else if (info->flow_type == UDP_V6_FLOW)
-			ndc->udp6_l4_hash = true;
-		else
+		switch (info->flow_type) {
+		case UDP_V4_FLOW:
+			ndc->l4_hash |= HV_UDP4_L4HASH;
+			break;
+
+		case UDP_V6_FLOW:
+			ndc->l4_hash |= HV_UDP6_L4HASH;
+			break;
+
+		default:
 			return -EOPNOTSUPP;
+		}
 
 		return 0;
 	}
 
 	if (info->data == (RXH_IP_SRC | RXH_IP_DST)) {
-		if (info->flow_type == UDP_V4_FLOW)
-			ndc->udp4_l4_hash = false;
-		else if (info->flow_type == UDP_V6_FLOW)
-			ndc->udp6_l4_hash = false;
-		else
+		switch (info->flow_type) {
+		case UDP_V4_FLOW:
+			ndc->l4_hash &= ~HV_UDP4_L4HASH;
+			break;
+
+		case UDP_V6_FLOW:
+			ndc->l4_hash &= ~HV_UDP6_L4HASH;
+			break;
+
+		default:
 			return -EOPNOTSUPP;
+		}
 
 		return 0;
 	}
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net-next,2/3] hv_netvsc: Add ethtool handler to set and get TCP hash levels
  2017-10-06 15:33 [PATCH net-next,0/3] hv_netvsc: support changing TCP hash level Haiyang Zhang
  2017-10-06 15:33 ` [PATCH net-next,1/3] hv_netvsc: Change the hash level variable to bit flags Haiyang Zhang
@ 2017-10-06 15:33 ` Haiyang Zhang
  2017-10-06 15:33 ` [PATCH net-next,3/3] hv_netvsc: Update netvsc Document for TCP hash level setting Haiyang Zhang
  2017-10-08 17:11 ` [PATCH net-next,0/3] hv_netvsc: support changing TCP hash level David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Haiyang Zhang @ 2017-10-06 15:33 UTC (permalink / raw)
  To: davem, netdev; +Cc: haiyangz, kys, sthemmin, olaf, vkuznets, linux-kernel

From: Haiyang Zhang <haiyangz@microsoft.com>

The patch supports the options to switch TCP hash level between
L3 and L4 by ethtool command. TCP over IPv4 and v6 can be set
differently. The default hash level is L4. We currently only
allow switching TX hash level from within the guests.

For example, for TCP over IPv4 on eth0:
To include TCP port numbers in hashing:
	ethtool -N eth0 rx-flow-hash tcp4 sdfn
To exclude TCP port numbers in hashing:
	ethtool -N eth0 rx-flow-hash tcp4 sd
To show TCP hash level:
	ethtool -n eth0 rx-flow-hash tcp4

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/net/hyperv/netvsc_drv.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 9bc7dbab9506..44746de3dd4c 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1264,8 +1264,15 @@ netvsc_get_rss_hash_opts(struct net_device_context *ndc,
 
 	switch (info->flow_type) {
 	case TCP_V4_FLOW:
+		if (ndc->l4_hash & HV_TCP4_L4HASH)
+			info->data |= l4_flag;
+
+		break;
+
 	case TCP_V6_FLOW:
-		info->data |= l4_flag;
+		if (ndc->l4_hash & HV_TCP6_L4HASH)
+			info->data |= l4_flag;
+
 		break;
 
 	case UDP_V4_FLOW:
@@ -1318,6 +1325,14 @@ static int netvsc_set_rss_hash_opts(struct net_device_context *ndc,
 	if (info->data == (RXH_IP_SRC | RXH_IP_DST |
 			   RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 		switch (info->flow_type) {
+		case TCP_V4_FLOW:
+			ndc->l4_hash |= HV_TCP4_L4HASH;
+			break;
+
+		case TCP_V6_FLOW:
+			ndc->l4_hash |= HV_TCP6_L4HASH;
+			break;
+
 		case UDP_V4_FLOW:
 			ndc->l4_hash |= HV_UDP4_L4HASH;
 			break;
@@ -1335,6 +1350,14 @@ static int netvsc_set_rss_hash_opts(struct net_device_context *ndc,
 
 	if (info->data == (RXH_IP_SRC | RXH_IP_DST)) {
 		switch (info->flow_type) {
+		case TCP_V4_FLOW:
+			ndc->l4_hash &= ~HV_TCP4_L4HASH;
+			break;
+
+		case TCP_V6_FLOW:
+			ndc->l4_hash &= ~HV_TCP6_L4HASH;
+			break;
+
 		case UDP_V4_FLOW:
 			ndc->l4_hash &= ~HV_UDP4_L4HASH;
 			break;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net-next,3/3] hv_netvsc: Update netvsc Document for TCP hash level setting
  2017-10-06 15:33 [PATCH net-next,0/3] hv_netvsc: support changing TCP hash level Haiyang Zhang
  2017-10-06 15:33 ` [PATCH net-next,1/3] hv_netvsc: Change the hash level variable to bit flags Haiyang Zhang
  2017-10-06 15:33 ` [PATCH net-next,2/3] hv_netvsc: Add ethtool handler to set and get TCP hash levels Haiyang Zhang
@ 2017-10-06 15:33 ` Haiyang Zhang
  2017-10-08 17:11 ` [PATCH net-next,0/3] hv_netvsc: support changing TCP hash level David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Haiyang Zhang @ 2017-10-06 15:33 UTC (permalink / raw)
  To: davem, netdev; +Cc: haiyangz, kys, sthemmin, olaf, vkuznets, linux-kernel

From: Haiyang Zhang <haiyangz@microsoft.com>

Update Documentation/networking/netvsc.txt for TCP hash level setting
and related info.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 Documentation/networking/netvsc.txt | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Documentation/networking/netvsc.txt b/Documentation/networking/netvsc.txt
index 93560fb1170a..92f5b31392fa 100644
--- a/Documentation/networking/netvsc.txt
+++ b/Documentation/networking/netvsc.txt
@@ -19,12 +19,12 @@ Features
 
   Receive Side Scaling
   --------------------
-  Hyper-V supports receive side scaling. For TCP, packets are
-  distributed among available queues based on IP address and port
+  Hyper-V supports receive side scaling. For TCP & UDP, packets can
+  be distributed among available queues based on IP address and port
   number.
 
-  For UDP, we can switch UDP hash level between L3 and L4 by ethtool
-  command. UDP over IPv4 and v6 can be set differently. The default
+  For TCP & UDP, we can switch hash level between L3 and L4 by ethtool
+  command. TCP/UDP over IPv4 and v6 can be set differently. The default
   hash level is L4. We currently only allow switching TX hash level
   from within the guests.
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next,0/3] hv_netvsc: support changing TCP hash level
  2017-10-06 15:33 [PATCH net-next,0/3] hv_netvsc: support changing TCP hash level Haiyang Zhang
                   ` (2 preceding siblings ...)
  2017-10-06 15:33 ` [PATCH net-next,3/3] hv_netvsc: Update netvsc Document for TCP hash level setting Haiyang Zhang
@ 2017-10-08 17:11 ` David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2017-10-08 17:11 UTC (permalink / raw)
  To: haiyangz, haiyangz; +Cc: netdev, kys, sthemmin, olaf, vkuznets, linux-kernel

From: Haiyang Zhang <haiyangz@exchange.microsoft.com>
Date: Fri,  6 Oct 2017 08:33:56 -0700

> From: Haiyang Zhang <haiyangz@microsoft.com>
> 
> The patch set simplifies the existing hash level switching code for
> UDP. It also adds the support for changing TCP hash level. So users
> can switch between L3 an L4 hash levels for TCP and UDP.

Series applied.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-10-08 17:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-06 15:33 [PATCH net-next,0/3] hv_netvsc: support changing TCP hash level Haiyang Zhang
2017-10-06 15:33 ` [PATCH net-next,1/3] hv_netvsc: Change the hash level variable to bit flags Haiyang Zhang
2017-10-06 15:33 ` [PATCH net-next,2/3] hv_netvsc: Add ethtool handler to set and get TCP hash levels Haiyang Zhang
2017-10-06 15:33 ` [PATCH net-next,3/3] hv_netvsc: Update netvsc Document for TCP hash level setting Haiyang Zhang
2017-10-08 17:11 ` [PATCH net-next,0/3] hv_netvsc: support changing TCP hash level David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.