diff options
| author | Piotr Raczynski <piotr.raczynski@intel.com> | 2023-05-15 21:03:17 +0200 | 
|---|---|---|
| committer | Tony Nguyen <anthony.l.nguyen@intel.com> | 2023-05-16 09:38:38 -0700 | 
| commit | 4aad5335969f25c4dc966a15c5497db3718538bb (patch) | |
| tree | d67e1744fdb2291c4ba427ae889b259757773f48 /drivers/net/ethernet/intel/ice/ice_lib.c | |
| parent | 524012c69ee1421d4a343291a0cfc1998ccba99a (diff) | |
ice: add individual interrupt allocation
Currently interrupt allocations, depending on a feature are distributed
in batches. Also, after allocation there is a series of operations that
distributes per irq settings through that batch of interrupts.
Although driver does not yet support dynamic interrupt allocation, keep
allocated interrupts in a pool and add allocation abstraction logic to
make code more flexible. Keep per interrupt information in the
ice_q_vector structure, which yields ice_vsi::base_vector redundant.
Also, as a result there are a few functions that can be removed.
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
Signed-off-by: Piotr Raczynski <piotr.raczynski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_lib.c')
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_lib.c | 228 | 
1 files changed, 18 insertions, 210 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index 25511240685d..fe908cf6da6a 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -1374,162 +1374,45 @@ out:   * ice_free_res - free a block of resources   * @res: pointer to the resource   * @index: starting index previously returned by ice_get_res - * @id: identifier to track owner   *   * Returns number of resources freed   */ -int ice_free_res(struct ice_res_tracker *res, u16 index, u16 id) +int ice_free_res(struct ice_res_tracker *res, u16 index)  { -	int count = 0; -	int i; -  	if (!res || index >= res->end)  		return -EINVAL; -	id |= ICE_RES_VALID_BIT; -	for (i = index; i < res->end && res->list[i] == id; i++) { -		res->list[i] = 0; -		count++; -	} - -	return count; -} - -/** - * ice_search_res - Search the tracker for a block of resources - * @res: pointer to the resource - * @needed: size of the block needed - * @id: identifier to track owner - * - * Returns the base item index of the block, or -ENOMEM for error - */ -static int ice_search_res(struct ice_res_tracker *res, u16 needed, u16 id) -{ -	u16 start = 0, end = 0; - -	if (needed > res->end) -		return -ENOMEM; - -	id |= ICE_RES_VALID_BIT; - -	do { -		/* skip already allocated entries */ -		if (res->list[end++] & ICE_RES_VALID_BIT) { -			start = end; -			if ((start + needed) > res->end) -				break; -		} - -		if (end == (start + needed)) { -			int i = start; - -			/* there was enough, so assign it to the requestor */ -			while (i != end) -				res->list[i++] = id; - -			return start; -		} -	} while (end < res->end); - -	return -ENOMEM; -} - -/** - * ice_get_free_res_count - Get free count from a resource tracker - * @res: Resource tracker instance - */ -static u16 ice_get_free_res_count(struct ice_res_tracker *res) -{ -	u16 i, count = 0; +	res->list[index] = 0; -	for (i = 0; i < res->end; i++) -		if (!(res->list[i] & ICE_RES_VALID_BIT)) -			count++; - -	return count; +	return 0;  }  /** - * ice_get_res - get a block of resources + * ice_get_res - get a resource from the tracker   * @pf: board private structure   * @res: pointer to the resource - * @needed: size of the block needed - * @id: identifier to track owner   * - * Returns the base item index of the block, or negative for error + * Returns the item index, or negative for error   */  int -ice_get_res(struct ice_pf *pf, struct ice_res_tracker *res, u16 needed, u16 id) +ice_get_res(struct ice_pf *pf, struct ice_res_tracker *res)  { -	if (!res || !pf) -		return -EINVAL; +	u16 i; -	if (!needed || needed > res->num_entries || id >= ICE_RES_VALID_BIT) { -		dev_err(ice_pf_to_dev(pf), "param err: needed=%d, num_entries = %d id=0x%04x\n", -			needed, res->num_entries, id); +	if (!res || !pf)  		return -EINVAL; -	} - -	return ice_search_res(res, needed, id); -} - -/** - * ice_vsi_setup_vector_base - Set up the base vector for the given VSI - * @vsi: ptr to the VSI - * - * This should only be called after ice_vsi_alloc_def() which allocates the - * corresponding SW VSI structure and initializes num_queue_pairs for the - * newly allocated VSI. - * - * Returns 0 on success or negative on failure - */ -static int ice_vsi_setup_vector_base(struct ice_vsi *vsi) -{ -	struct ice_pf *pf = vsi->back; -	u16 num_q_vectors, id; -	struct device *dev; -	int base; -	dev = ice_pf_to_dev(pf); -	/* SRIOV doesn't grab irq_tracker entries for each VSI */ -	if (vsi->type == ICE_VSI_VF) -		return 0; -	if (vsi->type == ICE_VSI_CHNL) -		return 0; - -	if (vsi->base_vector) { -		dev_dbg(dev, "VSI %d has non-zero base vector %d\n", -			vsi->vsi_num, vsi->base_vector); -		return -EEXIST; -	} - -	num_q_vectors = vsi->num_q_vectors; -	/* reserve slots from OS requested IRQs */ -	if (vsi->type == ICE_VSI_CTRL && vsi->vf) { -		struct ice_vsi *ctrl_vsi = ice_get_vf_ctrl_vsi(pf, vsi); - -		/* reuse VF control VSI interrupt vector */ -		if (ctrl_vsi) { -			vsi->base_vector = ctrl_vsi->base_vector; -			return 0; -		} +	/* skip already allocated entries */ +	for (i = 0; i < res->end; i++) +		if (!(res->list[i] & ICE_RES_VALID_BIT)) +			break; -		id = ICE_RES_VF_CTRL_VEC_ID; +	if (i < res->end) { +		res->list[i] = ICE_RES_VALID_BIT; +		return i;  	} else { -		id = vsi->idx; -	} - -	base = ice_get_res(pf, pf->irq_tracker, num_q_vectors, id); -	if (base < 0) { -		dev_err(dev, "%d MSI-X interrupts available. %s %d failed to get %d MSI-X vectors\n", -			ice_get_free_res_count(pf->irq_tracker), -			ice_vsi_type_str(vsi->type), vsi->idx, num_q_vectors); -		return -ENOENT; +		return -ENOMEM;  	} -	vsi->base_vector = (u16)base; -	pf->num_avail_sw_msix -= num_q_vectors; - -	return 0;  }  /** @@ -2388,50 +2271,6 @@ static void ice_vsi_set_tc_cfg(struct ice_vsi *vsi)  }  /** - * ice_vsi_set_q_vectors_reg_idx - set the HW register index for all q_vectors - * @vsi: VSI to set the q_vectors register index on - */ -static int -ice_vsi_set_q_vectors_reg_idx(struct ice_vsi *vsi) -{ -	u16 i; - -	if (!vsi || !vsi->q_vectors) -		return -EINVAL; - -	ice_for_each_q_vector(vsi, i) { -		struct ice_q_vector *q_vector = vsi->q_vectors[i]; - -		if (!q_vector) { -			dev_err(ice_pf_to_dev(vsi->back), "Failed to set reg_idx on q_vector %d VSI %d\n", -				i, vsi->vsi_num); -			goto clear_reg_idx; -		} - -		if (vsi->type == ICE_VSI_VF) { -			struct ice_vf *vf = vsi->vf; - -			q_vector->reg_idx = ice_calc_vf_reg_idx(vf, q_vector); -		} else { -			q_vector->reg_idx = -				q_vector->v_idx + vsi->base_vector; -		} -	} - -	return 0; - -clear_reg_idx: -	ice_for_each_q_vector(vsi, i) { -		struct ice_q_vector *q_vector = vsi->q_vectors[i]; - -		if (q_vector) -			q_vector->reg_idx = 0; -	} - -	return -EINVAL; -} - -/**   * ice_cfg_sw_lldp - Config switch rules for LLDP packet handling   * @vsi: the VSI being configured   * @tx: bool to determine Tx or Rx rule @@ -2675,14 +2514,6 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)  		if (ret)  			goto unroll_vsi_init; -		ret = ice_vsi_setup_vector_base(vsi); -		if (ret) -			goto unroll_alloc_q_vector; - -		ret = ice_vsi_set_q_vectors_reg_idx(vsi); -		if (ret) -			goto unroll_vector_base; -  		ret = ice_vsi_alloc_rings(vsi);  		if (ret)  			goto unroll_vector_base; @@ -2733,10 +2564,6 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)  		if (ret)  			goto unroll_alloc_q_vector; -		ret = ice_vsi_set_q_vectors_reg_idx(vsi); -		if (ret) -			goto unroll_vector_base; -  		ret = ice_vsi_alloc_ring_stats(vsi);  		if (ret)  			goto unroll_vector_base; @@ -2769,8 +2596,6 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)  unroll_vector_base:  	/* reclaim SW interrupts back to the common pool */ -	ice_free_res(pf->irq_tracker, vsi->base_vector, vsi->idx); -	pf->num_avail_sw_msix += vsi->num_q_vectors;  unroll_alloc_q_vector:  	ice_vsi_free_q_vectors(vsi);  unroll_vsi_init: @@ -2862,20 +2687,6 @@ void ice_vsi_decfg(struct ice_vsi *vsi)  	 * many interrupts each VF needs. SR-IOV MSIX resources are also  	 * cleared in the same manner.  	 */ -	if (vsi->type == ICE_VSI_CTRL && vsi->vf) { -		struct ice_vsi *ctrl_vsi = ice_get_vf_ctrl_vsi(pf, vsi); - -		if (!ctrl_vsi) { -			ice_free_res(pf->irq_tracker, vsi->base_vector, -				     ICE_RES_VF_CTRL_VEC_ID); -			pf->num_avail_sw_msix += vsi->num_q_vectors; -		} -	} else if (vsi->type != ICE_VSI_VF) { -		/* reclaim SW interrupts back to the common pool */ -		ice_free_res(pf->irq_tracker, vsi->base_vector, vsi->idx); -		pf->num_avail_sw_msix += vsi->num_q_vectors; -		vsi->base_vector = 0; -	}  	if (vsi->type == ICE_VSI_VF &&  	    vsi->agg_node && vsi->agg_node->valid) @@ -2992,7 +2803,6 @@ static void ice_vsi_release_msix(struct ice_vsi *vsi)  void ice_vsi_free_irq(struct ice_vsi *vsi)  {  	struct ice_pf *pf = vsi->back; -	int base = vsi->base_vector;  	int i;  	if (!vsi->q_vectors || !vsi->irqs_ready) @@ -3006,10 +2816,9 @@ void ice_vsi_free_irq(struct ice_vsi *vsi)  	ice_free_cpu_rx_rmap(vsi);  	ice_for_each_q_vector(vsi, i) { -		u16 vector = i + base;  		int irq_num; -		irq_num = pci_irq_vector(pf->pdev, vector); +		irq_num = vsi->q_vectors[i]->irq.virq;  		/* free only the irqs that were actually requested */  		if (!vsi->q_vectors[i] || @@ -3141,7 +2950,6 @@ void ice_dis_vsi(struct ice_vsi *vsi, bool locked)   */  void ice_vsi_dis_irq(struct ice_vsi *vsi)  { -	int base = vsi->base_vector;  	struct ice_pf *pf = vsi->back;  	struct ice_hw *hw = &pf->hw;  	u32 val; @@ -3188,7 +2996,7 @@ void ice_vsi_dis_irq(struct ice_vsi *vsi)  		return;  	ice_for_each_q_vector(vsi, i) -		synchronize_irq(pci_irq_vector(pf->pdev, i + base)); +		synchronize_irq(vsi->q_vectors[i]->irq.virq);  }  /**  | 
