All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically
@ 2023-05-26  6:02 Shradha Gupta
  2023-05-26  8:15 ` Simon Horman
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Shradha Gupta @ 2023-05-26  6:02 UTC (permalink / raw)
  To: linux-kernel, linux-hyperv, netdev
  Cc: Shradha Gupta, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
	Michael Kelley, David S. Miller, Steen Hegelund, Simon Horman

Allocate the size of rx indirection table dynamically in netvsc
from the value of size provided by OID_GEN_RECEIVE_SCALE_CAPABILITIES
query instead of using a constant value of ITAB_NUM.

Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
Tested-on: Ubuntu22 (azure VM, SKU size: Standard_F72s_v2)
Testcases:
1. ethtool -x eth0 output
2. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-Synthetic
3. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-SRIOV

---
Changes in v3:
 * Changed the data type of rx_table_sz to u32
 * Moved the rx indirection table free to rndis_filter_device_remove()
 * Device add will fail with error if not enough memory is available
 * Changed kzmalloc to kcalloc as suggested in checkpatch script
 * Removed redundant log if memory allocation failed.
---
 drivers/net/hyperv/hyperv_net.h   |  5 ++++-
 drivers/net/hyperv/netvsc_drv.c   | 10 ++++++----
 drivers/net/hyperv/rndis_filter.c | 27 +++++++++++++++++++++++----
 3 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index dd5919ec408b..c40868f287a9 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -74,6 +74,7 @@ struct ndis_recv_scale_cap { /* NDIS_RECEIVE_SCALE_CAPABILITIES */
 #define NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2   40
 
 #define ITAB_NUM 128
+#define ITAB_NUM_MAX 256
 
 struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */
 	struct ndis_obj_header hdr;
@@ -1034,7 +1035,9 @@ struct net_device_context {
 
 	u32 tx_table[VRSS_SEND_TAB_SIZE];
 
-	u16 rx_table[ITAB_NUM];
+	u16 *rx_table;
+
+	u32 rx_table_sz;
 
 	/* Ethtool settings */
 	u8 duplex;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 0103ff914024..3ba3c8fb28a5 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1747,7 +1747,9 @@ static u32 netvsc_get_rxfh_key_size(struct net_device *dev)
 
 static u32 netvsc_rss_indir_size(struct net_device *dev)
 {
-	return ITAB_NUM;
+	struct net_device_context *ndc = netdev_priv(dev);
+
+	return ndc->rx_table_sz;
 }
 
 static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
@@ -1766,7 +1768,7 @@ static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
 
 	rndis_dev = ndev->extension;
 	if (indir) {
-		for (i = 0; i < ITAB_NUM; i++)
+		for (i = 0; i < ndc->rx_table_sz; i++)
 			indir[i] = ndc->rx_table[i];
 	}
 
@@ -1792,11 +1794,11 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir,
 
 	rndis_dev = ndev->extension;
 	if (indir) {
-		for (i = 0; i < ITAB_NUM; i++)
+		for (i = 0; i < ndc->rx_table_sz; i++)
 			if (indir[i] >= ndev->num_chn)
 				return -EINVAL;
 
-		for (i = 0; i < ITAB_NUM; i++)
+		for (i = 0; i < ndc->rx_table_sz; i++)
 			ndc->rx_table[i] = indir[i];
 	}
 
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index eea777ec2541..dc7b9b326690 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -21,6 +21,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/ucs2_string.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 
 #include "hyperv_net.h"
 #include "netvsc_trace.h"
@@ -927,7 +928,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
 	struct rndis_set_request *set;
 	struct rndis_set_complete *set_complete;
 	u32 extlen = sizeof(struct ndis_recv_scale_param) +
-		     4 * ITAB_NUM + NETVSC_HASH_KEYLEN;
+		     4 * ndc->rx_table_sz + NETVSC_HASH_KEYLEN;
 	struct ndis_recv_scale_param *rssp;
 	u32 *itab;
 	u8 *keyp;
@@ -953,7 +954,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
 	rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
 			 NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 |
 			 NDIS_HASH_TCP_IPV6;
-	rssp->indirect_tabsize = 4*ITAB_NUM;
+	rssp->indirect_tabsize = 4 * ndc->rx_table_sz;
 	rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
 	rssp->hashkey_size = NETVSC_HASH_KEYLEN;
 	rssp->hashkey_offset = rssp->indirect_taboffset +
@@ -961,7 +962,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
 
 	/* Set indirection table entries */
 	itab = (u32 *)(rssp + 1);
-	for (i = 0; i < ITAB_NUM; i++)
+	for (i = 0; i < ndc->rx_table_sz; i++)
 		itab[i] = ndc->rx_table[i];
 
 	/* Set hask key values */
@@ -1548,6 +1549,17 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
 	if (ret || rsscap.num_recv_que < 2)
 		goto out;
 
+	if (rsscap.num_indirect_tabent &&
+	    rsscap.num_indirect_tabent <= ITAB_NUM_MAX)
+		ndc->rx_table_sz = rsscap.num_indirect_tabent;
+	else
+		ndc->rx_table_sz = ITAB_NUM;
+
+	ndc->rx_table = kcalloc(ndc->rx_table_sz, sizeof(u16),
+				GFP_KERNEL);
+	if (!ndc->rx_table)
+		goto err_dev_remv;
+
 	/* This guarantees that num_possible_rss_qs <= num_online_cpus */
 	num_possible_rss_qs = min_t(u32, num_online_cpus(),
 				    rsscap.num_recv_que);
@@ -1558,7 +1570,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
 	net_device->num_chn = min(net_device->max_chn, device_info->num_chn);
 
 	if (!netif_is_rxfh_configured(net)) {
-		for (i = 0; i < ITAB_NUM; i++)
+		for (i = 0; i < ndc->rx_table_sz; i++)
 			ndc->rx_table[i] = ethtool_rxfh_indir_default(
 						i, net_device->num_chn);
 	}
@@ -1596,11 +1608,18 @@ void rndis_filter_device_remove(struct hv_device *dev,
 				struct netvsc_device *net_dev)
 {
 	struct rndis_device *rndis_dev = net_dev->extension;
+	struct net_device *net = hv_get_drvdata(dev);
+	struct net_device_context *ndc = netdev_priv(net);
 
 	/* Halt and release the rndis device */
 	rndis_filter_halt_device(net_dev, rndis_dev);
 
 	netvsc_device_remove(dev);
+
+	ndc->rx_table_sz = 0;
+	kfree(ndc->rx_table);
+	ndc->rx_table = NULL;
+
 }
 
 int rndis_filter_open(struct netvsc_device *nvdev)
-- 
2.34.1


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

* Re: [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically
  2023-05-26  6:02 [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically Shradha Gupta
@ 2023-05-26  8:15 ` Simon Horman
  2023-05-29  9:39 ` Praveen Kumar
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Simon Horman @ 2023-05-26  8:15 UTC (permalink / raw)
  To: Shradha Gupta
  Cc: linux-kernel, linux-hyperv, netdev, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Michael Kelley, David S. Miller,
	Steen Hegelund

On Thu, May 25, 2023 at 11:02:29PM -0700, Shradha Gupta wrote:
> Allocate the size of rx indirection table dynamically in netvsc
> from the value of size provided by OID_GEN_RECEIVE_SCALE_CAPABILITIES
> query instead of using a constant value of ITAB_NUM.
> 
> Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>

> @@ -1548,6 +1549,17 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
>  	if (ret || rsscap.num_recv_que < 2)
>  		goto out;
>  
> +	if (rsscap.num_indirect_tabent &&
> +	    rsscap.num_indirect_tabent <= ITAB_NUM_MAX)
> +		ndc->rx_table_sz = rsscap.num_indirect_tabent;
> +	else
> +		ndc->rx_table_sz = ITAB_NUM;
> +
> +	ndc->rx_table = kcalloc(ndc->rx_table_sz, sizeof(u16),
> +				GFP_KERNEL);

nit: the above could fit on a single line.

> +	if (!ndc->rx_table)

I think you need to set ret to an error value here,
as err_dev_remv will call return ERR_PTR(ret).

> +		goto err_dev_remv;
> +
>  	/* This guarantees that num_possible_rss_qs <= num_online_cpus */
>  	num_possible_rss_qs = min_t(u32, num_online_cpus(),
>  				    rsscap.num_recv_que);
> @@ -1558,7 +1570,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
>  	net_device->num_chn = min(net_device->max_chn, device_info->num_chn);
>  
>  	if (!netif_is_rxfh_configured(net)) {
> -		for (i = 0; i < ITAB_NUM; i++)
> +		for (i = 0; i < ndc->rx_table_sz; i++)
>  			ndc->rx_table[i] = ethtool_rxfh_indir_default(
>  						i, net_device->num_chn);
>  	}
> @@ -1596,11 +1608,18 @@ void rndis_filter_device_remove(struct hv_device *dev,
>  				struct netvsc_device *net_dev)
>  {
>  	struct rndis_device *rndis_dev = net_dev->extension;
> +	struct net_device *net = hv_get_drvdata(dev);
> +	struct net_device_context *ndc = netdev_priv(net);

nit: Please use reverse xmas tree order - longest line to shortest -
     for local variable declaration sin networking code.

	struct rndis_device *rndis_dev = net_dev->extension;
	struct net_device *net = hv_get_drvdata(dev);
	struct net_device_context *ndc;

	ndc = netdev_priv(net);

>  
>  	/* Halt and release the rndis device */
>  	rndis_filter_halt_device(net_dev, rndis_dev);
>  
>  	netvsc_device_remove(dev);
> +
> +	ndc->rx_table_sz = 0;
> +	kfree(ndc->rx_table);
> +	ndc->rx_table = NULL;
> +
>  }
>  
>  int rndis_filter_open(struct netvsc_device *nvdev)

-- 
pw-bot: cr


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

* Re: [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically
  2023-05-26  6:02 [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically Shradha Gupta
  2023-05-26  8:15 ` Simon Horman
@ 2023-05-29  9:39 ` Praveen Kumar
  2023-05-29 11:17   ` Shradha Gupta
  2023-05-29 12:49 ` Christophe JAILLET
  2023-05-30 20:57 ` Haiyang Zhang
  3 siblings, 1 reply; 9+ messages in thread
From: Praveen Kumar @ 2023-05-29  9:39 UTC (permalink / raw)
  To: Shradha Gupta, linux-kernel, linux-hyperv, netdev
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, K. Y. Srinivasan,
	Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Michael Kelley,
	David S. Miller, Steen Hegelund, Simon Horman

On 5/26/2023 11:32 AM, Shradha Gupta wrote:
> Allocate the size of rx indirection table dynamically in netvsc
> from the value of size provided by OID_GEN_RECEIVE_SCALE_CAPABILITIES
> query instead of using a constant value of ITAB_NUM.
> 
> Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> Tested-on: Ubuntu22 (azure VM, SKU size: Standard_F72s_v2)
> Testcases:
> 1. ethtool -x eth0 output
> 2. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-Synthetic
> 3. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-SRIOV
> 
> ---
> Changes in v3:
>  * Changed the data type of rx_table_sz to u32
>  * Moved the rx indirection table free to rndis_filter_device_remove()
>  * Device add will fail with error if not enough memory is available
>  * Changed kzmalloc to kcalloc as suggested in checkpatch script
>  * Removed redundant log if memory allocation failed.
> ---
>  drivers/net/hyperv/hyperv_net.h   |  5 ++++-
>  drivers/net/hyperv/netvsc_drv.c   | 10 ++++++----
>  drivers/net/hyperv/rndis_filter.c | 27 +++++++++++++++++++++++----
>  3 files changed, 33 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
> index dd5919ec408b..c40868f287a9 100644
> --- a/drivers/net/hyperv/hyperv_net.h
> +++ b/drivers/net/hyperv/hyperv_net.h
> @@ -74,6 +74,7 @@ struct ndis_recv_scale_cap { /* NDIS_RECEIVE_SCALE_CAPABILITIES */
>  #define NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2   40
>  
>  #define ITAB_NUM 128
> +#define ITAB_NUM_MAX 256
>  
>  struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */
>  	struct ndis_obj_header hdr;
> @@ -1034,7 +1035,9 @@ struct net_device_context {
>  
>  	u32 tx_table[VRSS_SEND_TAB_SIZE];
>  
> -	u16 rx_table[ITAB_NUM];
> +	u16 *rx_table;
> +
> +	u32 rx_table_sz;
>  
>  	/* Ethtool settings */
>  	u8 duplex;
> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
> index 0103ff914024..3ba3c8fb28a5 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -1747,7 +1747,9 @@ static u32 netvsc_get_rxfh_key_size(struct net_device *dev)
>  
>  static u32 netvsc_rss_indir_size(struct net_device *dev)
>  {
> -	return ITAB_NUM;
> +	struct net_device_context *ndc = netdev_priv(dev);
> +
> +	return ndc->rx_table_sz;
>  }
>  
>  static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
> @@ -1766,7 +1768,7 @@ static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
>  
>  	rndis_dev = ndev->extension;
>  	if (indir) {
> -		for (i = 0; i < ITAB_NUM; i++)
> +		for (i = 0; i < ndc->rx_table_sz; i++)
>  			indir[i] = ndc->rx_table[i];
>  	}
>  
> @@ -1792,11 +1794,11 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir,
>  
>  	rndis_dev = ndev->extension;
>  	if (indir) {
> -		for (i = 0; i < ITAB_NUM; i++)
> +		for (i = 0; i < ndc->rx_table_sz; i++)
>  			if (indir[i] >= ndev->num_chn)
>  				return -EINVAL;
>  
> -		for (i = 0; i < ITAB_NUM; i++)
> +		for (i = 0; i < ndc->rx_table_sz; i++)
>  			ndc->rx_table[i] = indir[i];
>  	}
>  
> diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
> index eea777ec2541..dc7b9b326690 100644
> --- a/drivers/net/hyperv/rndis_filter.c
> +++ b/drivers/net/hyperv/rndis_filter.c
> @@ -21,6 +21,7 @@
>  #include <linux/rtnetlink.h>
>  #include <linux/ucs2_string.h>
>  #include <linux/string.h>
> +#include <linux/slab.h>
>  
>  #include "hyperv_net.h"
>  #include "netvsc_trace.h"
> @@ -927,7 +928,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
>  	struct rndis_set_request *set;
>  	struct rndis_set_complete *set_complete;
>  	u32 extlen = sizeof(struct ndis_recv_scale_param) +
> -		     4 * ITAB_NUM + NETVSC_HASH_KEYLEN;
> +		     4 * ndc->rx_table_sz + NETVSC_HASH_KEYLEN;
>  	struct ndis_recv_scale_param *rssp;
>  	u32 *itab;
>  	u8 *keyp;
> @@ -953,7 +954,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
>  	rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
>  			 NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 |
>  			 NDIS_HASH_TCP_IPV6;
> -	rssp->indirect_tabsize = 4*ITAB_NUM;
> +	rssp->indirect_tabsize = 4 * ndc->rx_table_sz;
>  	rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
>  	rssp->hashkey_size = NETVSC_HASH_KEYLEN;
>  	rssp->hashkey_offset = rssp->indirect_taboffset +
> @@ -961,7 +962,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
>  
>  	/* Set indirection table entries */
>  	itab = (u32 *)(rssp + 1);
> -	for (i = 0; i < ITAB_NUM; i++)
> +	for (i = 0; i < ndc->rx_table_sz; i++)
>  		itab[i] = ndc->rx_table[i];
>  
>  	/* Set hask key values */
> @@ -1548,6 +1549,17 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
>  	if (ret || rsscap.num_recv_que < 2)
>  		goto out;
>  
> +	if (rsscap.num_indirect_tabent &&
> +	    rsscap.num_indirect_tabent <= ITAB_NUM_MAX)
> +		ndc->rx_table_sz = rsscap.num_indirect_tabent;
> +	else
> +		ndc->rx_table_sz = ITAB_NUM;
> +
> +	ndc->rx_table = kcalloc(ndc->rx_table_sz, sizeof(u16),
> +				GFP_KERNEL);
> +	if (!ndc->rx_table)
> +		goto err_dev_remv;
> +
>  	/* This guarantees that num_possible_rss_qs <= num_online_cpus */
>  	num_possible_rss_qs = min_t(u32, num_online_cpus(),
>  				    rsscap.num_recv_que);
> @@ -1558,7 +1570,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
>  	net_device->num_chn = min(net_device->max_chn, device_info->num_chn);
>  
>  	if (!netif_is_rxfh_configured(net)) {
> -		for (i = 0; i < ITAB_NUM; i++)
> +		for (i = 0; i < ndc->rx_table_sz; i++)
>  			ndc->rx_table[i] = ethtool_rxfh_indir_default(
>  						i, net_device->num_chn);
>  	}
> @@ -1596,11 +1608,18 @@ void rndis_filter_device_remove(struct hv_device *dev,
>  				struct netvsc_device *net_dev)
>  {
>  	struct rndis_device *rndis_dev = net_dev->extension;
> +	struct net_device *net = hv_get_drvdata(dev);
> +	struct net_device_context *ndc = netdev_priv(net);
>  
>  	/* Halt and release the rndis device */
>  	rndis_filter_halt_device(net_dev, rndis_dev);
>  
>  	netvsc_device_remove(dev);

Shouldn't the netvsc_device_remove be called post table cleanup ? or better, the cleanup should happen as part of netvsc_device_remove operation ? This looks a bug to me as with remove operation, we already cleaned up the device and the association between context and device is removed.
> +
> +	ndc->rx_table_sz = 0;
> +	kfree(ndc->rx_table);
> +	ndc->rx_table = NULL;
> +
>  }
>  
>  int rndis_filter_open(struct netvsc_device *nvdev)


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

* Re: [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically
  2023-05-29  9:39 ` Praveen Kumar
@ 2023-05-29 11:17   ` Shradha Gupta
  2023-06-07  7:19     ` Praveen Kumar
  0 siblings, 1 reply; 9+ messages in thread
From: Shradha Gupta @ 2023-05-29 11:17 UTC (permalink / raw)
  To: Praveen Kumar
  Cc: linux-kernel, linux-hyperv, netdev, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Michael Kelley, David S. Miller,
	Steen Hegelund, Simon Horman

On Mon, May 29, 2023 at 03:09:49PM +0530, Praveen Kumar wrote:
> On 5/26/2023 11:32 AM, Shradha Gupta wrote:
> > Allocate the size of rx indirection table dynamically in netvsc
> > from the value of size provided by OID_GEN_RECEIVE_SCALE_CAPABILITIES
> > query instead of using a constant value of ITAB_NUM.
> > 
> > Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> > Tested-on: Ubuntu22 (azure VM, SKU size: Standard_F72s_v2)
> > Testcases:
> > 1. ethtool -x eth0 output
> > 2. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-Synthetic
> > 3. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-SRIOV
> > 
> > ---
> > Changes in v3:
> >  * Changed the data type of rx_table_sz to u32
> >  * Moved the rx indirection table free to rndis_filter_device_remove()
> >  * Device add will fail with error if not enough memory is available
> >  * Changed kzmalloc to kcalloc as suggested in checkpatch script
> >  * Removed redundant log if memory allocation failed.
> > ---
> >  drivers/net/hyperv/hyperv_net.h   |  5 ++++-
> >  drivers/net/hyperv/netvsc_drv.c   | 10 ++++++----
> >  drivers/net/hyperv/rndis_filter.c | 27 +++++++++++++++++++++++----
> >  3 files changed, 33 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
> > index dd5919ec408b..c40868f287a9 100644
> > --- a/drivers/net/hyperv/hyperv_net.h
> > +++ b/drivers/net/hyperv/hyperv_net.h
> > @@ -74,6 +74,7 @@ struct ndis_recv_scale_cap { /* NDIS_RECEIVE_SCALE_CAPABILITIES */
> >  #define NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2   40
> >  
> >  #define ITAB_NUM 128
> > +#define ITAB_NUM_MAX 256
> >  
> >  struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */
> >  	struct ndis_obj_header hdr;
> > @@ -1034,7 +1035,9 @@ struct net_device_context {
> >  
> >  	u32 tx_table[VRSS_SEND_TAB_SIZE];
> >  
> > -	u16 rx_table[ITAB_NUM];
> > +	u16 *rx_table;
> > +
> > +	u32 rx_table_sz;
> >  
> >  	/* Ethtool settings */
> >  	u8 duplex;
> > diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
> > index 0103ff914024..3ba3c8fb28a5 100644
> > --- a/drivers/net/hyperv/netvsc_drv.c
> > +++ b/drivers/net/hyperv/netvsc_drv.c
> > @@ -1747,7 +1747,9 @@ static u32 netvsc_get_rxfh_key_size(struct net_device *dev)
> >  
> >  static u32 netvsc_rss_indir_size(struct net_device *dev)
> >  {
> > -	return ITAB_NUM;
> > +	struct net_device_context *ndc = netdev_priv(dev);
> > +
> > +	return ndc->rx_table_sz;
> >  }
> >  
> >  static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
> > @@ -1766,7 +1768,7 @@ static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
> >  
> >  	rndis_dev = ndev->extension;
> >  	if (indir) {
> > -		for (i = 0; i < ITAB_NUM; i++)
> > +		for (i = 0; i < ndc->rx_table_sz; i++)
> >  			indir[i] = ndc->rx_table[i];
> >  	}
> >  
> > @@ -1792,11 +1794,11 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir,
> >  
> >  	rndis_dev = ndev->extension;
> >  	if (indir) {
> > -		for (i = 0; i < ITAB_NUM; i++)
> > +		for (i = 0; i < ndc->rx_table_sz; i++)
> >  			if (indir[i] >= ndev->num_chn)
> >  				return -EINVAL;
> >  
> > -		for (i = 0; i < ITAB_NUM; i++)
> > +		for (i = 0; i < ndc->rx_table_sz; i++)
> >  			ndc->rx_table[i] = indir[i];
> >  	}
> >  
> > diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
> > index eea777ec2541..dc7b9b326690 100644
> > --- a/drivers/net/hyperv/rndis_filter.c
> > +++ b/drivers/net/hyperv/rndis_filter.c
> > @@ -21,6 +21,7 @@
> >  #include <linux/rtnetlink.h>
> >  #include <linux/ucs2_string.h>
> >  #include <linux/string.h>
> > +#include <linux/slab.h>
> >  
> >  #include "hyperv_net.h"
> >  #include "netvsc_trace.h"
> > @@ -927,7 +928,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
> >  	struct rndis_set_request *set;
> >  	struct rndis_set_complete *set_complete;
> >  	u32 extlen = sizeof(struct ndis_recv_scale_param) +
> > -		     4 * ITAB_NUM + NETVSC_HASH_KEYLEN;
> > +		     4 * ndc->rx_table_sz + NETVSC_HASH_KEYLEN;
> >  	struct ndis_recv_scale_param *rssp;
> >  	u32 *itab;
> >  	u8 *keyp;
> > @@ -953,7 +954,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
> >  	rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
> >  			 NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 |
> >  			 NDIS_HASH_TCP_IPV6;
> > -	rssp->indirect_tabsize = 4*ITAB_NUM;
> > +	rssp->indirect_tabsize = 4 * ndc->rx_table_sz;
> >  	rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
> >  	rssp->hashkey_size = NETVSC_HASH_KEYLEN;
> >  	rssp->hashkey_offset = rssp->indirect_taboffset +
> > @@ -961,7 +962,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
> >  
> >  	/* Set indirection table entries */
> >  	itab = (u32 *)(rssp + 1);
> > -	for (i = 0; i < ITAB_NUM; i++)
> > +	for (i = 0; i < ndc->rx_table_sz; i++)
> >  		itab[i] = ndc->rx_table[i];
> >  
> >  	/* Set hask key values */
> > @@ -1548,6 +1549,17 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
> >  	if (ret || rsscap.num_recv_que < 2)
> >  		goto out;
> >  
> > +	if (rsscap.num_indirect_tabent &&
> > +	    rsscap.num_indirect_tabent <= ITAB_NUM_MAX)
> > +		ndc->rx_table_sz = rsscap.num_indirect_tabent;
> > +	else
> > +		ndc->rx_table_sz = ITAB_NUM;
> > +
> > +	ndc->rx_table = kcalloc(ndc->rx_table_sz, sizeof(u16),
> > +				GFP_KERNEL);
> > +	if (!ndc->rx_table)
> > +		goto err_dev_remv;
> > +
> >  	/* This guarantees that num_possible_rss_qs <= num_online_cpus */
> >  	num_possible_rss_qs = min_t(u32, num_online_cpus(),
> >  				    rsscap.num_recv_que);
> > @@ -1558,7 +1570,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
> >  	net_device->num_chn = min(net_device->max_chn, device_info->num_chn);
> >  
> >  	if (!netif_is_rxfh_configured(net)) {
> > -		for (i = 0; i < ITAB_NUM; i++)
> > +		for (i = 0; i < ndc->rx_table_sz; i++)
> >  			ndc->rx_table[i] = ethtool_rxfh_indir_default(
> >  						i, net_device->num_chn);
> >  	}
> > @@ -1596,11 +1608,18 @@ void rndis_filter_device_remove(struct hv_device *dev,
> >  				struct netvsc_device *net_dev)
> >  {
> >  	struct rndis_device *rndis_dev = net_dev->extension;
> > +	struct net_device *net = hv_get_drvdata(dev);
> > +	struct net_device_context *ndc = netdev_priv(net);
> >  
> >  	/* Halt and release the rndis device */
> >  	rndis_filter_halt_device(net_dev, rndis_dev);
> >  
> >  	netvsc_device_remove(dev);
> 
> Shouldn't the netvsc_device_remove be called post table cleanup ? or better, the cleanup should happen as part of netvsc_device_remove operation ? This looks a bug to me as with remove operation, we already cleaned up the device and the association between context and device is removed.

The netvsc_device_remove() function is responsible for cleaning up/removing the netvsc_device structures upon events like remove/suspend. The net_device and net_device_context structures(where the rx indirection table exists) remain untouched in netvsc_device_remove(). They(net_device, net_device_context) only get cleaned up in netvsc_remove(). So, the netvsc_device_remove() should not affect the cleanup for the rx indirection table, that we did.

> > +
> > +	ndc->rx_table_sz = 0;
> > +	kfree(ndc->rx_table);
> > +	ndc->rx_table = NULL;
> > +
> >  }
> >  
> >  int rndis_filter_open(struct netvsc_device *nvdev)

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

* Re: [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically
  2023-05-26  6:02 [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically Shradha Gupta
  2023-05-26  8:15 ` Simon Horman
  2023-05-29  9:39 ` Praveen Kumar
@ 2023-05-29 12:49 ` Christophe JAILLET
  2023-05-29 13:30   ` Shradha Gupta
  2023-05-30 20:57 ` Haiyang Zhang
  3 siblings, 1 reply; 9+ messages in thread
From: Christophe JAILLET @ 2023-05-29 12:49 UTC (permalink / raw)
  To: Shradha Gupta, linux-kernel, linux-hyperv, netdev
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, K. Y. Srinivasan,
	Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Michael Kelley,
	David S. Miller, Steen Hegelund, Simon Horman

Le 26/05/2023 à 08:02, Shradha Gupta a écrit :
> Allocate the size of rx indirection table dynamically in netvsc
> from the value of size provided by OID_GEN_RECEIVE_SCALE_CAPABILITIES
> query instead of using a constant value of ITAB_NUM.
> 
> Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> Tested-on: Ubuntu22 (azure VM, SKU size: Standard_F72s_v2)
> Testcases:
> 1. ethtool -x eth0 output
> 2. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-Synthetic
> 3. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-SRIOV
> 
> ---

[...]

> @@ -1596,11 +1608,18 @@ void rndis_filter_device_remove(struct hv_device *dev,
>   				struct netvsc_device *net_dev)
>   {
>   	struct rndis_device *rndis_dev = net_dev->extension;
> +	struct net_device *net = hv_get_drvdata(dev);
> +	struct net_device_context *ndc = netdev_priv(net);
>   
>   	/* Halt and release the rndis device */
>   	rndis_filter_halt_device(net_dev, rndis_dev);
>   
>   	netvsc_device_remove(dev);
> +
> +	ndc->rx_table_sz = 0;
> +	kfree(ndc->rx_table);
> +	ndc->rx_table = NULL;
> +

Nit: useless empty NL

>   }
>   
>   int rndis_filter_open(struct netvsc_device *nvdev)


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

* Re: [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically
  2023-05-29 12:49 ` Christophe JAILLET
@ 2023-05-29 13:30   ` Shradha Gupta
  2023-05-29 14:25     ` Christophe JAILLET
  0 siblings, 1 reply; 9+ messages in thread
From: Shradha Gupta @ 2023-05-29 13:30 UTC (permalink / raw)
  To: Christophe JAILLET
  Cc: linux-kernel, linux-hyperv, netdev, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Michael Kelley, David S. Miller,
	Steen Hegelund, Simon Horman

Thanks for the comment Christophe.
On Mon, May 29, 2023 at 02:49:15PM +0200, Christophe JAILLET wrote:
> Le 26/05/2023 ?? 08:02, Shradha Gupta a ??crit??:
> >Allocate the size of rx indirection table dynamically in netvsc
> >from the value of size provided by OID_GEN_RECEIVE_SCALE_CAPABILITIES
> >query instead of using a constant value of ITAB_NUM.
> >
> >Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> >Tested-on: Ubuntu22 (azure VM, SKU size: Standard_F72s_v2)
> >Testcases:
> >1. ethtool -x eth0 output
> >2. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-Synthetic
> >3. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-SRIOV
> >
> >---
> 
> [...]
> 
> >@@ -1596,11 +1608,18 @@ void rndis_filter_device_remove(struct hv_device *dev,
> >  				struct netvsc_device *net_dev)
> >  {
> >  	struct rndis_device *rndis_dev = net_dev->extension;
> >+	struct net_device *net = hv_get_drvdata(dev);
> >+	struct net_device_context *ndc = netdev_priv(net);
> >  	/* Halt and release the rndis device */
> >  	rndis_filter_halt_device(net_dev, rndis_dev);
> >  	netvsc_device_remove(dev);
> >+
> >+	ndc->rx_table_sz = 0;
> >+	kfree(ndc->rx_table);
> >+	ndc->rx_table = NULL;
> >+
> 
> Nit: useless empty NL
This is to prevent any potential double free, or accessing freed memory, etc.
As requested by Haiyang in v2 patch
> 
> >  }
> >  int rndis_filter_open(struct netvsc_device *nvdev)

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

* Re: [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically
  2023-05-29 13:30   ` Shradha Gupta
@ 2023-05-29 14:25     ` Christophe JAILLET
  0 siblings, 0 replies; 9+ messages in thread
From: Christophe JAILLET @ 2023-05-29 14:25 UTC (permalink / raw)
  To: Shradha Gupta
  Cc: linux-kernel, linux-hyperv, netdev, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Michael Kelley, David S. Miller,
	Steen Hegelund, Simon Horman

Le 29/05/2023 à 15:30, Shradha Gupta a écrit :
> Thanks for the comment Christophe.
> On Mon, May 29, 2023 at 02:49:15PM +0200, Christophe JAILLET wrote:
>> Le 26/05/2023 ?? 08:02, Shradha Gupta a ??crit??:
>>> Allocate the size of rx indirection table dynamically in netvsc
>> >from the value of size provided by OID_GEN_RECEIVE_SCALE_CAPABILITIES
>>> query instead of using a constant value of ITAB_NUM.
>>>
>>> Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
>>> Tested-on: Ubuntu22 (azure VM, SKU size: Standard_F72s_v2)
>>> Testcases:
>>> 1. ethtool -x eth0 output
>>> 2. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-Synthetic
>>> 3. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-SRIOV
>>>
>>> ---
>>
>> [...]
>>
>>> @@ -1596,11 +1608,18 @@ void rndis_filter_device_remove(struct hv_device *dev,
>>>   				struct netvsc_device *net_dev)
>>>   {
>>>   	struct rndis_device *rndis_dev = net_dev->extension;
>>> +	struct net_device *net = hv_get_drvdata(dev);
>>> +	struct net_device_context *ndc = netdev_priv(net);
>>>   	/* Halt and release the rndis device */
>>>   	rndis_filter_halt_device(net_dev, rndis_dev);
>>>   	netvsc_device_remove(dev);
>>> +
>>> +	ndc->rx_table_sz = 0;
>>> +	kfree(ndc->rx_table);
>>> +	ndc->rx_table = NULL;
>>> +
>>
>> Nit: useless empty NL
> This is to prevent any potential double free, or accessing freed memory, etc.
> As requested by Haiyang in v2 patch

Setting ndc->rx_table to NULL is fine, but there is a useless *newline* 
(NL) just after.
If you have to send a v4, you can save a line of code.

CJ

>>
>>>   }
>>>   int rndis_filter_open(struct netvsc_device *nvdev)
> 


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

* RE: [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically
  2023-05-26  6:02 [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically Shradha Gupta
                   ` (2 preceding siblings ...)
  2023-05-29 12:49 ` Christophe JAILLET
@ 2023-05-30 20:57 ` Haiyang Zhang
  3 siblings, 0 replies; 9+ messages in thread
From: Haiyang Zhang @ 2023-05-30 20:57 UTC (permalink / raw)
  To: Shradha Gupta, linux-kernel, linux-hyperv, netdev
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, KY Srinivasan,
	Wei Liu, Dexuan Cui, Long Li, Michael Kelley (LINUX),
	David S. Miller, Steen Hegelund, Simon Horman



> -----Original Message-----
> From: Shradha Gupta <shradhagupta@linux.microsoft.com>
> Sent: Friday, May 26, 2023 2:02 AM
> To: linux-kernel@vger.kernel.org; linux-hyperv@vger.kernel.org;
> netdev@vger.kernel.org
> Cc: Shradha Gupta <shradhagupta@linux.microsoft.com>; Eric Dumazet
> <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo Abeni
> <pabeni@redhat.com>; KY Srinivasan <kys@microsoft.com>; Haiyang Zhang
> <haiyangz@microsoft.com>; Wei Liu <wei.liu@kernel.org>; Dexuan Cui
> <decui@microsoft.com>; Long Li <longli@microsoft.com>; Michael Kelley
> (LINUX) <mikelley@microsoft.com>; David S. Miller <davem@davemloft.net>;
> Steen Hegelund <steen.hegelund@microchip.com>; Simon Horman
> <simon.horman@corigine.com>
> Subject: [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically
> 
> Allocate the size of rx indirection table dynamically in netvsc
> from the value of size provided by OID_GEN_RECEIVE_SCALE_CAPABILITIES
> query instead of using a constant value of ITAB_NUM.
> 
> Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> Tested-on: Ubuntu22 (azure VM, SKU size: Standard_F72s_v2)
> Testcases:
> 1. ethtool -x eth0 output
> 2. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-
> NTTTCP-Synthetic
> 3. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-
> NTTTCP-SRIOV

Thank you!

Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>



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

* Re: [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically
  2023-05-29 11:17   ` Shradha Gupta
@ 2023-06-07  7:19     ` Praveen Kumar
  0 siblings, 0 replies; 9+ messages in thread
From: Praveen Kumar @ 2023-06-07  7:19 UTC (permalink / raw)
  To: Shradha Gupta
  Cc: linux-kernel, linux-hyperv, netdev, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Michael Kelley, David S. Miller,
	Steen Hegelund, Simon Horman

On 5/29/2023 4:47 PM, Shradha Gupta wrote:
> On Mon, May 29, 2023 at 03:09:49PM +0530, Praveen Kumar wrote:
>> On 5/26/2023 11:32 AM, Shradha Gupta wrote:
>>> Allocate the size of rx indirection table dynamically in netvsc
>>> from the value of size provided by OID_GEN_RECEIVE_SCALE_CAPABILITIES
>>> query instead of using a constant value of ITAB_NUM.
>>>
>>> Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
>>> Tested-on: Ubuntu22 (azure VM, SKU size: Standard_F72s_v2)
>>> Testcases:
>>> 1. ethtool -x eth0 output
>>> 2. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-Synthetic
>>> 3. LISA testcase:PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-SRIOV
>>>
>>> ---
>>> Changes in v3:
>>>  * Changed the data type of rx_table_sz to u32
>>>  * Moved the rx indirection table free to rndis_filter_device_remove()
>>>  * Device add will fail with error if not enough memory is available
>>>  * Changed kzmalloc to kcalloc as suggested in checkpatch script
>>>  * Removed redundant log if memory allocation failed.
>>> ---
>>>  drivers/net/hyperv/hyperv_net.h   |  5 ++++-
>>>  drivers/net/hyperv/netvsc_drv.c   | 10 ++++++----
>>>  drivers/net/hyperv/rndis_filter.c | 27 +++++++++++++++++++++++----
>>>  3 files changed, 33 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
>>> index dd5919ec408b..c40868f287a9 100644
>>> --- a/drivers/net/hyperv/hyperv_net.h
>>> +++ b/drivers/net/hyperv/hyperv_net.h
>>> @@ -74,6 +74,7 @@ struct ndis_recv_scale_cap { /* NDIS_RECEIVE_SCALE_CAPABILITIES */
>>>  #define NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2   40
>>>  
>>>  #define ITAB_NUM 128
>>> +#define ITAB_NUM_MAX 256
>>>  
>>>  struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */
>>>  	struct ndis_obj_header hdr;
>>> @@ -1034,7 +1035,9 @@ struct net_device_context {
>>>  
>>>  	u32 tx_table[VRSS_SEND_TAB_SIZE];
>>>  
>>> -	u16 rx_table[ITAB_NUM];
>>> +	u16 *rx_table;
>>> +
>>> +	u32 rx_table_sz;
>>>  
>>>  	/* Ethtool settings */
>>>  	u8 duplex;
>>> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
>>> index 0103ff914024..3ba3c8fb28a5 100644
>>> --- a/drivers/net/hyperv/netvsc_drv.c
>>> +++ b/drivers/net/hyperv/netvsc_drv.c
>>> @@ -1747,7 +1747,9 @@ static u32 netvsc_get_rxfh_key_size(struct net_device *dev)
>>>  
>>>  static u32 netvsc_rss_indir_size(struct net_device *dev)
>>>  {
>>> -	return ITAB_NUM;
>>> +	struct net_device_context *ndc = netdev_priv(dev);
>>> +
>>> +	return ndc->rx_table_sz;
>>>  }
>>>  
>>>  static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
>>> @@ -1766,7 +1768,7 @@ static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
>>>  
>>>  	rndis_dev = ndev->extension;
>>>  	if (indir) {
>>> -		for (i = 0; i < ITAB_NUM; i++)
>>> +		for (i = 0; i < ndc->rx_table_sz; i++)
>>>  			indir[i] = ndc->rx_table[i];
>>>  	}
>>>  
>>> @@ -1792,11 +1794,11 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir,
>>>  
>>>  	rndis_dev = ndev->extension;
>>>  	if (indir) {
>>> -		for (i = 0; i < ITAB_NUM; i++)
>>> +		for (i = 0; i < ndc->rx_table_sz; i++)
>>>  			if (indir[i] >= ndev->num_chn)
>>>  				return -EINVAL;
>>>  
>>> -		for (i = 0; i < ITAB_NUM; i++)
>>> +		for (i = 0; i < ndc->rx_table_sz; i++)
>>>  			ndc->rx_table[i] = indir[i];
>>>  	}
>>>  
>>> diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
>>> index eea777ec2541..dc7b9b326690 100644
>>> --- a/drivers/net/hyperv/rndis_filter.c
>>> +++ b/drivers/net/hyperv/rndis_filter.c
>>> @@ -21,6 +21,7 @@
>>>  #include <linux/rtnetlink.h>
>>>  #include <linux/ucs2_string.h>
>>>  #include <linux/string.h>
>>> +#include <linux/slab.h>
>>>  
>>>  #include "hyperv_net.h"
>>>  #include "netvsc_trace.h"
>>> @@ -927,7 +928,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
>>>  	struct rndis_set_request *set;
>>>  	struct rndis_set_complete *set_complete;
>>>  	u32 extlen = sizeof(struct ndis_recv_scale_param) +
>>> -		     4 * ITAB_NUM + NETVSC_HASH_KEYLEN;
>>> +		     4 * ndc->rx_table_sz + NETVSC_HASH_KEYLEN;
>>>  	struct ndis_recv_scale_param *rssp;
>>>  	u32 *itab;
>>>  	u8 *keyp;
>>> @@ -953,7 +954,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
>>>  	rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
>>>  			 NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 |
>>>  			 NDIS_HASH_TCP_IPV6;
>>> -	rssp->indirect_tabsize = 4*ITAB_NUM;
>>> +	rssp->indirect_tabsize = 4 * ndc->rx_table_sz;
>>>  	rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
>>>  	rssp->hashkey_size = NETVSC_HASH_KEYLEN;
>>>  	rssp->hashkey_offset = rssp->indirect_taboffset +
>>> @@ -961,7 +962,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
>>>  
>>>  	/* Set indirection table entries */
>>>  	itab = (u32 *)(rssp + 1);
>>> -	for (i = 0; i < ITAB_NUM; i++)
>>> +	for (i = 0; i < ndc->rx_table_sz; i++)
>>>  		itab[i] = ndc->rx_table[i];
>>>  
>>>  	/* Set hask key values */
>>> @@ -1548,6 +1549,17 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
>>>  	if (ret || rsscap.num_recv_que < 2)
>>>  		goto out;
>>>  
>>> +	if (rsscap.num_indirect_tabent &&
>>> +	    rsscap.num_indirect_tabent <= ITAB_NUM_MAX)
>>> +		ndc->rx_table_sz = rsscap.num_indirect_tabent;
>>> +	else
>>> +		ndc->rx_table_sz = ITAB_NUM;
>>> +
>>> +	ndc->rx_table = kcalloc(ndc->rx_table_sz, sizeof(u16),
>>> +				GFP_KERNEL);
>>> +	if (!ndc->rx_table)
>>> +		goto err_dev_remv;
>>> +
>>>  	/* This guarantees that num_possible_rss_qs <= num_online_cpus */
>>>  	num_possible_rss_qs = min_t(u32, num_online_cpus(),
>>>  				    rsscap.num_recv_que);
>>> @@ -1558,7 +1570,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
>>>  	net_device->num_chn = min(net_device->max_chn, device_info->num_chn);
>>>  
>>>  	if (!netif_is_rxfh_configured(net)) {
>>> -		for (i = 0; i < ITAB_NUM; i++)
>>> +		for (i = 0; i < ndc->rx_table_sz; i++)
>>>  			ndc->rx_table[i] = ethtool_rxfh_indir_default(
>>>  						i, net_device->num_chn);
>>>  	}
>>> @@ -1596,11 +1608,18 @@ void rndis_filter_device_remove(struct hv_device *dev,
>>>  				struct netvsc_device *net_dev)
>>>  {
>>>  	struct rndis_device *rndis_dev = net_dev->extension;
>>> +	struct net_device *net = hv_get_drvdata(dev);
>>> +	struct net_device_context *ndc = netdev_priv(net);
>>>  
>>>  	/* Halt and release the rndis device */
>>>  	rndis_filter_halt_device(net_dev, rndis_dev);
>>>  
>>>  	netvsc_device_remove(dev);
>>
>> Shouldn't the netvsc_device_remove be called post table cleanup ? or better, the cleanup should happen as part of netvsc_device_remove operation ? This looks a bug to me as with remove operation, we already cleaned up the device and the association between context and device is removed.
> 
> The netvsc_device_remove() function is responsible for cleaning up/removing the netvsc_device structures upon events like remove/suspend. The net_device and net_device_context structures(where the rx indirection table exists) remain untouched in netvsc_device_remove(). They(net_device, net_device_context) only get cleaned up in netvsc_remove(). So, the netvsc_device_remove() should not affect the cleanup for the rx indirection table, that we did.
> 

Thanks.

Reviewed-by: Praveen Kumar <kumarpraveen@linux.microsoft.com>


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

end of thread, other threads:[~2023-06-07  7:19 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-26  6:02 [PATCH v3] hv_netvsc: Allocate rx indirection table size dynamically Shradha Gupta
2023-05-26  8:15 ` Simon Horman
2023-05-29  9:39 ` Praveen Kumar
2023-05-29 11:17   ` Shradha Gupta
2023-06-07  7:19     ` Praveen Kumar
2023-05-29 12:49 ` Christophe JAILLET
2023-05-29 13:30   ` Shradha Gupta
2023-05-29 14:25     ` Christophe JAILLET
2023-05-30 20:57 ` Haiyang Zhang

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.