Skip to content

Commit

Permalink
hv_netvsc: Allocate rx indirection table size dynamically
Browse files Browse the repository at this point in the history
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>
Reviewed-by: Haiyang Zhang <haiyangz@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
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Shradha Gupta authored and David S. Miller committed Jun 7, 2023
1 parent ae28ea5 commit 4cab498
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 9 deletions.
5 changes: 4 additions & 1 deletion drivers/net/hyperv/hyperv_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 6 additions & 4 deletions drivers/net/hyperv/netvsc_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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];
}

Expand All @@ -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];
}

Expand Down
29 changes: 25 additions & 4 deletions drivers/net/hyperv/rndis_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand All @@ -953,15 +954,15 @@ 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 +
rssp->indirect_tabsize;

/* 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 */
Expand Down Expand Up @@ -1548,6 +1549,18 @@ 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) {
ret = -ENOMEM;
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);
Expand All @@ -1558,7 +1571,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);
}
Expand Down Expand Up @@ -1596,11 +1609,19 @@ 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;

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)
Expand Down

0 comments on commit 4cab498

Please sign in to comment.