Skip to content

Commit de2b1e0

Browse files
Somnath Koturdavem330
authored andcommitted
be2net: Fix provisioning of RSS for VFs in multi-partition configurations
Currently, we do not distribute queue resources to enable RSS for VFs in multi-channel/partition configurations. Fix this by having each PF(SRIOV capable) calculate it's share of the 15 RSS Policy Tables available per port before provisioning resources for all the VFs. This proportional share calculation is done based on division of the PF's MAX VFs with the Total MAX VFs on that port. It also needs to learn about the no: of NIC PFs on the port and subtract that from the 15 RSS Policy Tables on the port. Signed-off-by: Somnath Kotur <[email protected]> Signed-off-by: Sathya Perla <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 45f13df commit de2b1e0

File tree

4 files changed

+130
-30
lines changed

4 files changed

+130
-30
lines changed

drivers/net/ethernet/emulex/benet/be.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@
9797
* SURF/DPDK
9898
*/
9999

100-
#define MAX_RSS_IFACES 15
100+
#define MAX_PORT_RSS_TABLES 15
101+
#define MAX_NIC_FUNCS 16
101102
#define MAX_RX_QS 32
102103
#define MAX_EVT_QS 32
103104
#define MAX_TX_QS 32
@@ -445,6 +446,16 @@ struct be_resources {
445446
u32 if_cap_flags;
446447
u32 vf_if_cap_flags; /* VF if capability flags */
447448
u32 flags;
449+
/* Calculated PF Pool's share of RSS Tables. This is not enforced by
450+
* the FW, but is a self-imposed driver limitation.
451+
*/
452+
u16 max_rss_tables;
453+
};
454+
455+
/* These are port-wide values */
456+
struct be_port_resources {
457+
u16 max_vfs;
458+
u16 nic_pfs;
448459
};
449460

450461
#define be_is_os2bmc_enabled(adapter) (adapter->flags & BE_FLAGS_OS2BMC)
@@ -635,6 +646,8 @@ struct be_adapter {
635646
#define be_max_rxqs(adapter) (adapter->res.max_rx_qs)
636647
#define be_max_eqs(adapter) (adapter->res.max_evt_qs)
637648
#define be_if_cap_flags(adapter) (adapter->res.if_cap_flags)
649+
#define be_max_pf_pool_rss_tables(adapter) \
650+
(adapter->pool_res.max_rss_tables)
638651

639652
static inline u16 be_max_qs(struct be_adapter *adapter)
640653
{

drivers/net/ethernet/emulex/benet/be_cmds.c

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4363,9 +4363,35 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
43634363
return status;
43644364
}
43654365

4366+
/* This routine returns a list of all the NIC PF_nums in the adapter */
4367+
u16 be_get_nic_pf_num_list(u8 *buf, u32 desc_count, u16 *nic_pf_nums)
4368+
{
4369+
struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
4370+
struct be_pcie_res_desc *pcie = NULL;
4371+
int i;
4372+
u16 nic_pf_count = 0;
4373+
4374+
for (i = 0; i < desc_count; i++) {
4375+
if (hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V0 ||
4376+
hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V1) {
4377+
pcie = (struct be_pcie_res_desc *)hdr;
4378+
if (pcie->pf_state && (pcie->pf_type == MISSION_NIC ||
4379+
pcie->pf_type == MISSION_RDMA)) {
4380+
nic_pf_nums[nic_pf_count++] = pcie->pf_num;
4381+
}
4382+
}
4383+
4384+
hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
4385+
hdr = (void *)hdr + hdr->desc_len;
4386+
}
4387+
return nic_pf_count;
4388+
}
4389+
43664390
/* Will use MBOX only if MCCQ has not been created */
43674391
int be_cmd_get_profile_config(struct be_adapter *adapter,
4368-
struct be_resources *res, u8 query, u8 domain)
4392+
struct be_resources *res,
4393+
struct be_port_resources *port_res,
4394+
u8 profile_type, u8 query, u8 domain)
43694395
{
43704396
struct be_cmd_resp_get_profile_config *resp;
43714397
struct be_cmd_req_get_profile_config *req;
@@ -4392,7 +4418,7 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
43924418

43934419
if (!lancer_chip(adapter))
43944420
req->hdr.version = 1;
4395-
req->type = ACTIVE_PROFILE_TYPE;
4421+
req->type = profile_type;
43964422
req->hdr.domain = domain;
43974423

43984424
/* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the
@@ -4409,6 +4435,28 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
44094435
resp = cmd.va;
44104436
desc_count = le16_to_cpu(resp->desc_count);
44114437

4438+
if (port_res) {
4439+
u16 nic_pf_cnt = 0, i;
4440+
u16 nic_pf_num_list[MAX_NIC_FUNCS];
4441+
4442+
nic_pf_cnt = be_get_nic_pf_num_list(resp->func_param,
4443+
desc_count,
4444+
nic_pf_num_list);
4445+
4446+
for (i = 0; i < nic_pf_cnt; i++) {
4447+
nic = be_get_func_nic_desc(resp->func_param, desc_count,
4448+
nic_pf_num_list[i]);
4449+
if (nic->link_param == adapter->port_num) {
4450+
port_res->nic_pfs++;
4451+
pcie = be_get_pcie_desc(resp->func_param,
4452+
desc_count,
4453+
nic_pf_num_list[i]);
4454+
port_res->max_vfs += le16_to_cpu(pcie->num_vfs);
4455+
}
4456+
}
4457+
return status;
4458+
}
4459+
44124460
pcie = be_get_pcie_desc(resp->func_param, desc_count,
44134461
adapter->pf_num);
44144462
if (pcie)

drivers/net/ethernet/emulex/benet/be_cmds.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2130,6 +2130,9 @@ struct be_cmd_req_set_ext_fat_caps {
21302130
#define IMM_SHIFT 6 /* Immediate */
21312131
#define NOSV_SHIFT 7 /* No save */
21322132

2133+
#define MISSION_NIC 1
2134+
#define MISSION_RDMA 8
2135+
21332136
struct be_res_desc_hdr {
21342137
u8 desc_type;
21352138
u8 desc_len;
@@ -2246,6 +2249,7 @@ struct be_cmd_req_get_profile_config {
22462249
struct be_cmd_req_hdr hdr;
22472250
u8 rsvd;
22482251
#define ACTIVE_PROFILE_TYPE 0x2
2252+
#define SAVED_PROFILE_TYPE 0x0
22492253
#define QUERY_MODIFIABLE_FIELDS_TYPE BIT(3)
22502254
u8 type;
22512255
u16 rsvd1;
@@ -2451,7 +2455,9 @@ int be_cmd_query_port_name(struct be_adapter *adapter);
24512455
int be_cmd_get_func_config(struct be_adapter *adapter,
24522456
struct be_resources *res);
24532457
int be_cmd_get_profile_config(struct be_adapter *adapter,
2454-
struct be_resources *res, u8 query, u8 domain);
2458+
struct be_resources *res,
2459+
struct be_port_resources *port_res,
2460+
u8 profile_type, u8 query, u8 domain);
24552461
int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile);
24562462
int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
24572463
int vf_num);

drivers/net/ethernet/emulex/benet/be_main.c

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3784,28 +3784,27 @@ static void be_calculate_vf_res(struct be_adapter *adapter, u16 num_vfs,
37843784
struct be_resources res_mod = {0};
37853785
u16 num_vf_qs = 1;
37863786

3787-
/* Distribute the queue resources among the PF and it's VFs
3788-
* Do not distribute queue resources in multi-channel configuration.
3789-
*/
3790-
if (num_vfs && !be_is_mc(adapter)) {
3791-
/* Divide the rx queues evenly among the VFs and the PF, capped
3792-
* at VF-EQ-count. Any remainder queues belong to the PF.
3793-
*/
3787+
/* Distribute the queue resources among the PF and it's VFs */
3788+
if (num_vfs) {
3789+
/* Divide the rx queues evenly among the VFs and the PF, capped
3790+
* at VF-EQ-count. Any remainder queues belong to the PF.
3791+
*/
37943792
num_vf_qs = min(SH_VF_MAX_NIC_EQS,
37953793
res.max_rss_qs / (num_vfs + 1));
37963794

3797-
/* Skyhawk-R chip supports only MAX_RSS_IFACES RSS capable
3798-
* interfaces per port. Provide RSS on VFs, only if number
3799-
* of VFs requested is less than MAX_RSS_IFACES limit.
3795+
/* Skyhawk-R chip supports only MAX_PORT_RSS_TABLES
3796+
* RSS Tables per port. Provide RSS on VFs, only if number of
3797+
* VFs requested is less than it's PF Pool's RSS Tables limit.
38003798
*/
3801-
if (num_vfs >= MAX_RSS_IFACES)
3799+
if (num_vfs >= be_max_pf_pool_rss_tables(adapter))
38023800
num_vf_qs = 1;
38033801
}
38043802

38053803
/* Resource with fields set to all '1's by GET_PROFILE_CONFIG cmd,
38063804
* which are modifiable using SET_PROFILE_CONFIG cmd.
38073805
*/
3808-
be_cmd_get_profile_config(adapter, &res_mod, RESOURCE_MODIFIABLE, 0);
3806+
be_cmd_get_profile_config(adapter, &res_mod, NULL, ACTIVE_PROFILE_TYPE,
3807+
RESOURCE_MODIFIABLE, 0);
38093808

38103809
/* If RSS IFACE capability flags are modifiable for a VF, set the
38113810
* capability flag as valid and set RSS and DEFQ_RSS IFACE flags if
@@ -3903,7 +3902,8 @@ static int be_vfs_if_create(struct be_adapter *adapter)
39033902

39043903
for_all_vfs(adapter, vf_cfg, vf) {
39053904
if (!BE3_chip(adapter)) {
3906-
status = be_cmd_get_profile_config(adapter, &res,
3905+
status = be_cmd_get_profile_config(adapter, &res, NULL,
3906+
ACTIVE_PROFILE_TYPE,
39073907
RESOURCE_LIMITS,
39083908
vf + 1);
39093909
if (!status) {
@@ -4088,8 +4088,9 @@ static void BEx_get_resources(struct be_adapter *adapter,
40884088
/* On a SuperNIC profile, the driver needs to use the
40894089
* GET_PROFILE_CONFIG cmd to query the per-function TXQ limits
40904090
*/
4091-
be_cmd_get_profile_config(adapter, &super_nic_res,
4092-
RESOURCE_LIMITS, 0);
4091+
be_cmd_get_profile_config(adapter, &super_nic_res, NULL,
4092+
ACTIVE_PROFILE_TYPE, RESOURCE_LIMITS,
4093+
0);
40934094
/* Some old versions of BE3 FW don't report max_tx_qs value */
40944095
res->max_tx_qs = super_nic_res.max_tx_qs ? : BE3_MAX_TX_QS;
40954096
} else {
@@ -4128,12 +4129,38 @@ static void be_setup_init(struct be_adapter *adapter)
41284129
adapter->cmd_privileges = MIN_PRIVILEGES;
41294130
}
41304131

4132+
/* HW supports only MAX_PORT_RSS_TABLES RSS Policy Tables per port.
4133+
* However, this HW limitation is not exposed to the host via any SLI cmd.
4134+
* As a result, in the case of SRIOV and in particular multi-partition configs
4135+
* the driver needs to calcuate a proportional share of RSS Tables per PF-pool
4136+
* for distribution between the VFs. This self-imposed limit will determine the
4137+
* no: of VFs for which RSS can be enabled.
4138+
*/
4139+
void be_calculate_pf_pool_rss_tables(struct be_adapter *adapter)
4140+
{
4141+
struct be_port_resources port_res = {0};
4142+
u8 rss_tables_on_port;
4143+
u16 max_vfs = be_max_vfs(adapter);
4144+
4145+
be_cmd_get_profile_config(adapter, NULL, &port_res, SAVED_PROFILE_TYPE,
4146+
RESOURCE_LIMITS, 0);
4147+
4148+
rss_tables_on_port = MAX_PORT_RSS_TABLES - port_res.nic_pfs;
4149+
4150+
/* Each PF Pool's RSS Tables limit =
4151+
* PF's Max VFs / Total_Max_VFs on Port * RSS Tables on Port
4152+
*/
4153+
adapter->pool_res.max_rss_tables =
4154+
max_vfs * rss_tables_on_port / port_res.max_vfs;
4155+
}
4156+
41314157
static int be_get_sriov_config(struct be_adapter *adapter)
41324158
{
41334159
struct be_resources res = {0};
41344160
int max_vfs, old_vfs;
41354161

4136-
be_cmd_get_profile_config(adapter, &res, RESOURCE_LIMITS, 0);
4162+
be_cmd_get_profile_config(adapter, &res, NULL, ACTIVE_PROFILE_TYPE,
4163+
RESOURCE_LIMITS, 0);
41374164

41384165
/* Some old versions of BE3 FW don't report max_vfs value */
41394166
if (BE3_chip(adapter) && !res.max_vfs) {
@@ -4157,6 +4184,12 @@ static int be_get_sriov_config(struct be_adapter *adapter)
41574184
adapter->num_vfs = old_vfs;
41584185
}
41594186

4187+
if (skyhawk_chip(adapter) && be_max_vfs(adapter) && !old_vfs) {
4188+
be_calculate_pf_pool_rss_tables(adapter);
4189+
dev_info(&adapter->pdev->dev,
4190+
"RSS can be enabled for all VFs if num_vfs <= %d\n",
4191+
be_max_pf_pool_rss_tables(adapter));
4192+
}
41604193
return 0;
41614194
}
41624195

@@ -4272,15 +4305,6 @@ static int be_get_config(struct be_adapter *adapter)
42724305
"Using profile 0x%x\n", profile_id);
42734306
}
42744307

4275-
status = be_get_resources(adapter);
4276-
if (status)
4277-
return status;
4278-
4279-
adapter->pmac_id = kcalloc(be_max_uc(adapter),
4280-
sizeof(*adapter->pmac_id), GFP_KERNEL);
4281-
if (!adapter->pmac_id)
4282-
return -ENOMEM;
4283-
42844308
return 0;
42854309
}
42864310

@@ -4481,13 +4505,22 @@ static int be_setup(struct be_adapter *adapter)
44814505
return status;
44824506
}
44834507

4508+
status = be_get_config(adapter);
4509+
if (status)
4510+
goto err;
4511+
44844512
if (!BE2_chip(adapter) && be_physfn(adapter))
44854513
be_alloc_sriov_res(adapter);
44864514

4487-
status = be_get_config(adapter);
4515+
status = be_get_resources(adapter);
44884516
if (status)
44894517
goto err;
44904518

4519+
adapter->pmac_id = kcalloc(be_max_uc(adapter),
4520+
sizeof(*adapter->pmac_id), GFP_KERNEL);
4521+
if (!adapter->pmac_id)
4522+
return -ENOMEM;
4523+
44914524
status = be_msix_enable(adapter);
44924525
if (status)
44934526
goto err;

0 commit comments

Comments
 (0)