Skip to content

Commit cc94d6c

Browse files
nrescobarkuba-moo
authored andcommitted
enic: Adjust used MSI-X wq/rq/cq/interrupt resources in a more robust way
Instead of failing to use MSI-X if resources aren't configured exactly right, use the resources we do have. Since we could start using large numbers of rq resources, we do limit the rq count to what netif_get_num_default_rss_queues() recommends. Co-developed-by: John Daley <johndale@cisco.com> Signed-off-by: John Daley <johndale@cisco.com> Co-developed-by: Satish Kharat <satishkh@cisco.com> Signed-off-by: Satish Kharat <satishkh@cisco.com> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: Nelson Escobar <neescoba@cisco.com> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Link: https://patch.msgid.link/20241113-remove_vic_resource_limits-v4-5-a34cf8570c67@cisco.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent a64e549 commit cc94d6c

File tree

1 file changed

+57
-59
lines changed

1 file changed

+57
-59
lines changed

drivers/net/ethernet/cisco/enic/enic_main.c

Lines changed: 57 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,109 +2442,107 @@ static void enic_tx_hang_reset(struct work_struct *work)
24422442

24432443
static int enic_set_intr_mode(struct enic *enic)
24442444
{
2445-
unsigned int n = min_t(unsigned int, enic->rq_count, ENIC_RQ_MAX);
2446-
unsigned int m = min_t(unsigned int, enic->wq_count, ENIC_WQ_MAX);
24472445
unsigned int i;
2446+
int num_intr;
24482447

24492448
/* Set interrupt mode (INTx, MSI, MSI-X) depending
24502449
* on system capabilities.
24512450
*
2452-
* Try MSI-X first
2451+
* We need a minimum of 1 RQ, 1 WQ, and 2 CQs
24532452
*
2454-
* We need n RQs, m WQs, n+m CQs, and n+m+2 INTRs
2455-
* (the second to last INTR is used for WQ/RQ errors)
2456-
* (the last INTR is used for notifications)
24572453
*/
24582454

2459-
for (i = 0; i < enic->intr_avail; i++)
2460-
enic->msix_entry[i].entry = i;
2461-
2462-
/* Use multiple RQs if RSS is enabled
2463-
*/
2464-
2465-
if (ENIC_SETTING(enic, RSS) &&
2466-
enic->config.intr_mode < 1 &&
2467-
enic->rq_count >= n &&
2468-
enic->wq_count >= m &&
2469-
enic->cq_count >= n + m &&
2470-
enic->intr_count >= n + m + 2) {
2471-
2472-
if (pci_enable_msix_range(enic->pdev, enic->msix_entry,
2473-
n + m + 2, n + m + 2) > 0) {
2474-
2475-
enic->rq_count = n;
2476-
enic->wq_count = m;
2477-
enic->cq_count = n + m;
2478-
enic->intr_count = n + m + 2;
2479-
2480-
vnic_dev_set_intr_mode(enic->vdev,
2481-
VNIC_DEV_INTR_MODE_MSIX);
2482-
2483-
return 0;
2484-
}
2455+
if (enic->rq_avail < 1 || enic->wq_avail < 1 || enic->cq_avail < 2) {
2456+
dev_err(enic_get_dev(enic),
2457+
"Not enough resources available rq: %d wq: %d cq: %d\n",
2458+
enic->rq_avail, enic->wq_avail,
2459+
enic->cq_avail);
2460+
return -ENOSPC;
24852461
}
24862462

2463+
/* if RSS isn't set, then we can only use one RQ */
2464+
if (!ENIC_SETTING(enic, RSS))
2465+
enic->rq_avail = 1;
2466+
2467+
/* Try MSI-X first */
24872468
if (enic->config.intr_mode < 1 &&
2488-
enic->rq_count >= 1 &&
2489-
enic->wq_count >= m &&
2490-
enic->cq_count >= 1 + m &&
2491-
enic->intr_count >= 1 + m + 2) {
2492-
if (pci_enable_msix_range(enic->pdev, enic->msix_entry,
2493-
1 + m + 2, 1 + m + 2) > 0) {
2494-
2495-
enic->rq_count = 1;
2496-
enic->wq_count = m;
2497-
enic->cq_count = 1 + m;
2498-
enic->intr_count = 1 + m + 2;
2469+
enic->intr_avail >= ENIC_MSIX_MIN_INTR) {
2470+
unsigned int max_queues;
2471+
unsigned int rq_default;
2472+
unsigned int rq_avail;
2473+
unsigned int wq_avail;
2474+
2475+
for (i = 0; i < enic->intr_avail; i++)
2476+
enic->msix_entry[i].entry = i;
2477+
2478+
num_intr = pci_enable_msix_range(enic->pdev, enic->msix_entry,
2479+
ENIC_MSIX_MIN_INTR,
2480+
enic->intr_avail);
2481+
if (num_intr > 0) {
2482+
wq_avail = min(enic->wq_avail, ENIC_WQ_MAX);
2483+
rq_default = netif_get_num_default_rss_queues();
2484+
rq_avail = min3(enic->rq_avail, ENIC_RQ_MAX, rq_default);
2485+
max_queues = min(enic->cq_avail,
2486+
enic->intr_avail - ENIC_MSIX_RESERVED_INTR);
2487+
2488+
if (wq_avail + rq_avail <= max_queues) {
2489+
enic->rq_count = rq_avail;
2490+
enic->wq_count = wq_avail;
2491+
} else {
2492+
/* recalculate wq/rq count */
2493+
if (rq_avail < wq_avail) {
2494+
enic->rq_count = min(rq_avail, max_queues / 2);
2495+
enic->wq_count = max_queues - enic->rq_count;
2496+
} else {
2497+
enic->wq_count = min(wq_avail, max_queues / 2);
2498+
enic->rq_count = max_queues - enic->wq_count;
2499+
}
2500+
}
2501+
enic->cq_count = enic->rq_count + enic->wq_count;
2502+
enic->intr_count = enic->cq_count + ENIC_MSIX_RESERVED_INTR;
24992503

25002504
vnic_dev_set_intr_mode(enic->vdev,
2501-
VNIC_DEV_INTR_MODE_MSIX);
2502-
2505+
VNIC_DEV_INTR_MODE_MSIX);
2506+
enic->intr_avail = num_intr;
25032507
return 0;
25042508
}
25052509
}
25062510

25072511
/* Next try MSI
25082512
*
2509-
* We need 1 RQ, 1 WQ, 2 CQs, and 1 INTR
2513+
* We need 1 INTR
25102514
*/
25112515

25122516
if (enic->config.intr_mode < 2 &&
2513-
enic->rq_count >= 1 &&
2514-
enic->wq_count >= 1 &&
2515-
enic->cq_count >= 2 &&
2516-
enic->intr_count >= 1 &&
2517+
enic->intr_avail >= 1 &&
25172518
!pci_enable_msi(enic->pdev)) {
25182519

25192520
enic->rq_count = 1;
25202521
enic->wq_count = 1;
25212522
enic->cq_count = 2;
25222523
enic->intr_count = 1;
2523-
2524+
enic->intr_avail = 1;
25242525
vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_MSI);
25252526

25262527
return 0;
25272528
}
25282529

25292530
/* Next try INTx
25302531
*
2531-
* We need 1 RQ, 1 WQ, 2 CQs, and 3 INTRs
2532+
* We need 3 INTRs
25322533
* (the first INTR is used for WQ/RQ)
25332534
* (the second INTR is used for WQ/RQ errors)
25342535
* (the last INTR is used for notifications)
25352536
*/
25362537

25372538
if (enic->config.intr_mode < 3 &&
2538-
enic->rq_count >= 1 &&
2539-
enic->wq_count >= 1 &&
2540-
enic->cq_count >= 2 &&
2541-
enic->intr_count >= 3) {
2539+
enic->intr_avail >= 3) {
25422540

25432541
enic->rq_count = 1;
25442542
enic->wq_count = 1;
25452543
enic->cq_count = 2;
25462544
enic->intr_count = 3;
2547-
2545+
enic->intr_avail = 3;
25482546
vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_INTX);
25492547

25502548
return 0;
@@ -2762,8 +2760,8 @@ static void enic_kdump_kernel_config(struct enic *enic)
27622760
{
27632761
if (is_kdump_kernel()) {
27642762
dev_info(enic_get_dev(enic), "Running from within kdump kernel. Using minimal resources\n");
2765-
enic->rq_count = 1;
2766-
enic->wq_count = 1;
2763+
enic->rq_avail = 1;
2764+
enic->wq_avail = 1;
27672765
enic->config.rq_desc_count = ENIC_MIN_RQ_DESCS;
27682766
enic->config.wq_desc_count = ENIC_MIN_WQ_DESCS;
27692767
enic->config.mtu = min_t(u16, 1500, enic->config.mtu);

0 commit comments

Comments
 (0)