enic: Move enic resource adjustments to separate function

Move the enic resource adjustments out of enic_set_intr_mode() and into
its own function, enic_adjust_resources().

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-6-a34cf8570c67@cisco.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Nelson Escobar 2024-11-13 23:56:38 +00:00 committed by Jakub Kicinski
parent cc94d6c4d4
commit 374f6c04df

View File

@ -2448,30 +2448,11 @@ static int enic_set_intr_mode(struct enic *enic)
/* Set interrupt mode (INTx, MSI, MSI-X) depending
* on system capabilities.
*
* We need a minimum of 1 RQ, 1 WQ, and 2 CQs
*
* Try MSI-X first
*/
if (enic->rq_avail < 1 || enic->wq_avail < 1 || enic->cq_avail < 2) {
dev_err(enic_get_dev(enic),
"Not enough resources available rq: %d wq: %d cq: %d\n",
enic->rq_avail, enic->wq_avail,
enic->cq_avail);
return -ENOSPC;
}
/* if RSS isn't set, then we can only use one RQ */
if (!ENIC_SETTING(enic, RSS))
enic->rq_avail = 1;
/* Try MSI-X first */
if (enic->config.intr_mode < 1 &&
enic->intr_avail >= ENIC_MSIX_MIN_INTR) {
unsigned int max_queues;
unsigned int rq_default;
unsigned int rq_avail;
unsigned int wq_avail;
for (i = 0; i < enic->intr_avail; i++)
enic->msix_entry[i].entry = i;
@ -2479,28 +2460,6 @@ static int enic_set_intr_mode(struct enic *enic)
ENIC_MSIX_MIN_INTR,
enic->intr_avail);
if (num_intr > 0) {
wq_avail = min(enic->wq_avail, ENIC_WQ_MAX);
rq_default = netif_get_num_default_rss_queues();
rq_avail = min3(enic->rq_avail, ENIC_RQ_MAX, rq_default);
max_queues = min(enic->cq_avail,
enic->intr_avail - ENIC_MSIX_RESERVED_INTR);
if (wq_avail + rq_avail <= max_queues) {
enic->rq_count = rq_avail;
enic->wq_count = wq_avail;
} else {
/* recalculate wq/rq count */
if (rq_avail < wq_avail) {
enic->rq_count = min(rq_avail, max_queues / 2);
enic->wq_count = max_queues - enic->rq_count;
} else {
enic->wq_count = min(wq_avail, max_queues / 2);
enic->rq_count = max_queues - enic->wq_count;
}
}
enic->cq_count = enic->rq_count + enic->wq_count;
enic->intr_count = enic->cq_count + ENIC_MSIX_RESERVED_INTR;
vnic_dev_set_intr_mode(enic->vdev,
VNIC_DEV_INTR_MODE_MSIX);
enic->intr_avail = num_intr;
@ -2516,14 +2475,8 @@ static int enic_set_intr_mode(struct enic *enic)
if (enic->config.intr_mode < 2 &&
enic->intr_avail >= 1 &&
!pci_enable_msi(enic->pdev)) {
enic->rq_count = 1;
enic->wq_count = 1;
enic->cq_count = 2;
enic->intr_count = 1;
enic->intr_avail = 1;
vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_MSI);
return 0;
}
@ -2537,14 +2490,8 @@ static int enic_set_intr_mode(struct enic *enic)
if (enic->config.intr_mode < 3 &&
enic->intr_avail >= 3) {
enic->rq_count = 1;
enic->wq_count = 1;
enic->cq_count = 2;
enic->intr_count = 3;
enic->intr_avail = 3;
vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_INTX);
return 0;
}
@ -2569,6 +2516,67 @@ static void enic_clear_intr_mode(struct enic *enic)
vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_UNKNOWN);
}
static int enic_adjust_resources(struct enic *enic)
{
unsigned int max_queues;
unsigned int rq_default;
unsigned int rq_avail;
unsigned int wq_avail;
if (enic->rq_avail < 1 || enic->wq_avail < 1 || enic->cq_avail < 2) {
dev_err(enic_get_dev(enic),
"Not enough resources available rq: %d wq: %d cq: %d\n",
enic->rq_avail, enic->wq_avail,
enic->cq_avail);
return -ENOSPC;
}
/* if RSS isn't set, then we can only use one RQ */
if (!ENIC_SETTING(enic, RSS))
enic->rq_avail = 1;
switch (vnic_dev_get_intr_mode(enic->vdev)) {
case VNIC_DEV_INTR_MODE_INTX:
case VNIC_DEV_INTR_MODE_MSI:
enic->rq_count = 1;
enic->wq_count = 1;
enic->cq_count = 2;
enic->intr_count = enic->intr_avail;
break;
case VNIC_DEV_INTR_MODE_MSIX:
/* Adjust the number of wqs/rqs/cqs/interrupts that will be
* used based on which resource is the most constrained
*/
wq_avail = min(enic->wq_avail, ENIC_WQ_MAX);
rq_default = netif_get_num_default_rss_queues();
rq_avail = min3(enic->rq_avail, ENIC_RQ_MAX, rq_default);
max_queues = min(enic->cq_avail,
enic->intr_avail - ENIC_MSIX_RESERVED_INTR);
if (wq_avail + rq_avail <= max_queues) {
enic->rq_count = rq_avail;
enic->wq_count = wq_avail;
} else {
/* recalculate wq/rq count */
if (rq_avail < wq_avail) {
enic->rq_count = min(rq_avail, max_queues / 2);
enic->wq_count = max_queues - enic->rq_count;
} else {
enic->wq_count = min(wq_avail, max_queues / 2);
enic->rq_count = max_queues - enic->wq_count;
}
}
enic->cq_count = enic->rq_count + enic->wq_count;
enic->intr_count = enic->cq_count + ENIC_MSIX_RESERVED_INTR;
break;
default:
dev_err(enic_get_dev(enic), "Unknown interrupt mode\n");
return -EINVAL;
}
return 0;
}
static void enic_get_queue_stats_rx(struct net_device *dev, int idx,
struct netdev_queue_stats_rx *rxs)
{
@ -2807,9 +2815,7 @@ static int enic_dev_init(struct enic *enic)
*/
enic_kdump_kernel_config(enic);
/* Set interrupt mode based on resource counts and system
* capabilities
*/
/* Set interrupt mode based on system capabilities */
err = enic_set_intr_mode(enic);
if (err) {
@ -2818,6 +2824,13 @@ static int enic_dev_init(struct enic *enic)
goto err_out_free_vnic_resources;
}
/* Adjust resource counts based on most constrained resources */
err = enic_adjust_resources(enic);
if (err) {
dev_err(dev, "Failed to adjust resources\n");
goto err_out_free_vnic_resources;
}
/* Allocate and configure vNIC resources
*/