Commit 741106f7 authored by Tony Nguyen's avatar Tony Nguyen
Browse files

ice: Improve MSI-X fallback logic



Currently if the driver is unable to get all the MSI-X vectors it wants, it
falls back to the minimum configuration which equates to a single Tx/Rx
traffic queue pair. Instead of using the minimum configuration, if given
more vectors than the minimum, utilize those vectors for additional traffic
queues after accounting for other interrupts.

Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
Tested-by: default avatarTony Brelinski <tonyx.brelinski@intel.com>
parent fe6cd890
Loading
Loading
Loading
Loading
+25 −15
Original line number Diff line number Diff line
@@ -3391,39 +3391,41 @@ static int ice_init_pf(struct ice_pf *pf)
 */
static int ice_ena_msix_range(struct ice_pf *pf)
{
	int v_left, v_actual, v_other, v_budget = 0;
	struct device *dev = ice_pf_to_dev(pf);
	int v_left, v_actual, v_budget = 0;
	int needed, err, i;

	v_left = pf->hw.func_caps.common_cap.num_msix_vectors;

	/* reserve one vector for miscellaneous handler */
	needed = 1;
	/* reserve for LAN miscellaneous handler */
	needed = ICE_MIN_LAN_OICR_MSIX;
	if (v_left < needed)
		goto no_hw_vecs_left_err;
	v_budget += needed;
	v_left -= needed;

	/* reserve vectors for LAN traffic */
	needed = min_t(int, num_online_cpus(), v_left);
	/* reserve for flow director */
	if (test_bit(ICE_FLAG_FD_ENA, pf->flags)) {
		needed = ICE_FDIR_MSIX;
		if (v_left < needed)
			goto no_hw_vecs_left_err;
	pf->num_lan_msix = needed;
		v_budget += needed;
		v_left -= needed;
	}

	/* reserve one vector for flow director */
	if (test_bit(ICE_FLAG_FD_ENA, pf->flags)) {
		needed = ICE_FDIR_MSIX;
	/* total used for non-traffic vectors */
	v_other = v_budget;

	/* reserve vectors for LAN traffic */
	needed = min_t(int, num_online_cpus(), v_left);
	if (v_left < needed)
		goto no_hw_vecs_left_err;
	pf->num_lan_msix = needed;
	v_budget += needed;
	v_left -= needed;
	}

	pf->msix_entries = devm_kcalloc(dev, v_budget,
					sizeof(*pf->msix_entries), GFP_KERNEL);

	if (!pf->msix_entries) {
		err = -ENOMEM;
		goto exit_err;
@@ -3435,7 +3437,6 @@ static int ice_ena_msix_range(struct ice_pf *pf)
	/* actually reserve the vectors */
	v_actual = pci_enable_msix_range(pf->pdev, pf->msix_entries,
					 ICE_MIN_MSIX, v_budget);

	if (v_actual < 0) {
		dev_err(dev, "unable to reserve MSI-X vectors\n");
		err = v_actual;
@@ -3452,7 +3453,16 @@ static int ice_ena_msix_range(struct ice_pf *pf)
			err = -ERANGE;
			goto msix_err;
		} else {
			int v_traffic = v_actual - v_other;

			if (v_actual == ICE_MIN_MSIX ||
			    v_traffic < ICE_MIN_LAN_TXRX_MSIX)
				pf->num_lan_msix = ICE_MIN_LAN_TXRX_MSIX;
			else
				pf->num_lan_msix = v_traffic;

			dev_notice(dev, "Enabled %d MSI-X vectors for LAN traffic.\n",
				   pf->num_lan_msix);
		}
	}