mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-04 08:04:24 -04:00
ice: refactor VF control VSI interrupt handling
All VF control VSIs share the same interrupt vector. Currently, a helper function dedicated for that directly sets ice_vsi::base_vector. Use helper that returns pointer to first found VF control VSI instead. Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Tested-by: Rafal Romanowski <rafal.romanowski@intel.com> Signed-off-by: Piotr Raczynski <piotr.raczynski@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
committed by
Tony Nguyen
parent
05018936a1
commit
369bb5a2a9
@@ -1473,36 +1473,6 @@ ice_get_res(struct ice_pf *pf, struct ice_res_tracker *res, u16 needed, u16 id)
|
||||
return ice_search_res(res, needed, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_get_vf_ctrl_res - Get VF control VSI resource
|
||||
* @pf: pointer to the PF structure
|
||||
* @vsi: the VSI to allocate a resource for
|
||||
*
|
||||
* Look up whether another VF has already allocated the control VSI resource.
|
||||
* If so, re-use this resource so that we share it among all VFs.
|
||||
*
|
||||
* Otherwise, allocate the resource and return it.
|
||||
*/
|
||||
static int ice_get_vf_ctrl_res(struct ice_pf *pf, struct ice_vsi *vsi)
|
||||
{
|
||||
struct ice_vf *vf;
|
||||
unsigned int bkt;
|
||||
int base;
|
||||
|
||||
rcu_read_lock();
|
||||
ice_for_each_vf_rcu(pf, bkt, vf) {
|
||||
if (vf != vsi->vf && vf->ctrl_vsi_idx != ICE_NO_VSI) {
|
||||
base = pf->vsi[vf->ctrl_vsi_idx]->base_vector;
|
||||
rcu_read_unlock();
|
||||
return base;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return ice_get_res(pf, pf->irq_tracker, vsi->num_q_vectors,
|
||||
ICE_RES_VF_CTRL_VEC_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vsi_setup_vector_base - Set up the base vector for the given VSI
|
||||
* @vsi: ptr to the VSI
|
||||
@@ -1516,8 +1486,8 @@ static int ice_get_vf_ctrl_res(struct ice_pf *pf, struct ice_vsi *vsi)
|
||||
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;
|
||||
u16 num_q_vectors;
|
||||
int base;
|
||||
|
||||
dev = ice_pf_to_dev(pf);
|
||||
@@ -1536,12 +1506,20 @@ static int ice_vsi_setup_vector_base(struct ice_vsi *vsi)
|
||||
num_q_vectors = vsi->num_q_vectors;
|
||||
/* reserve slots from OS requested IRQs */
|
||||
if (vsi->type == ICE_VSI_CTRL && vsi->vf) {
|
||||
base = ice_get_vf_ctrl_res(pf, vsi);
|
||||
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;
|
||||
}
|
||||
|
||||
id = ICE_RES_VF_CTRL_VEC_ID;
|
||||
} else {
|
||||
base = ice_get_res(pf, pf->irq_tracker, num_q_vectors,
|
||||
vsi->idx);
|
||||
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),
|
||||
@@ -2611,37 +2589,6 @@ static void ice_set_agg_vsi(struct ice_vsi *vsi)
|
||||
vsi->agg_node->num_vsis);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_free_vf_ctrl_res - Free the VF control VSI resource
|
||||
* @pf: pointer to PF structure
|
||||
* @vsi: the VSI to free resources for
|
||||
*
|
||||
* Check if the VF control VSI resource is still in use. If no VF is using it
|
||||
* any more, release the VSI resource. Otherwise, leave it to be cleaned up
|
||||
* once no other VF uses it.
|
||||
*/
|
||||
static void ice_free_vf_ctrl_res(struct ice_pf *pf, struct ice_vsi *vsi)
|
||||
{
|
||||
struct ice_vf *vf;
|
||||
unsigned int bkt;
|
||||
|
||||
rcu_read_lock();
|
||||
ice_for_each_vf_rcu(pf, bkt, vf) {
|
||||
if (vf != vsi->vf && vf->ctrl_vsi_idx != ICE_NO_VSI) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
/* No other VFs left that have control VSI. It is now safe to reclaim
|
||||
* SW interrupts back to the common pool.
|
||||
*/
|
||||
ice_free_res(pf->irq_tracker, vsi->base_vector,
|
||||
ICE_RES_VF_CTRL_VEC_ID);
|
||||
pf->num_avail_sw_msix += vsi->num_q_vectors;
|
||||
}
|
||||
|
||||
static int ice_vsi_cfg_tc_lan(struct ice_pf *pf, struct ice_vsi *vsi)
|
||||
{
|
||||
u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
|
||||
@@ -2916,7 +2863,13 @@ void ice_vsi_decfg(struct ice_vsi *vsi)
|
||||
* cleared in the same manner.
|
||||
*/
|
||||
if (vsi->type == ICE_VSI_CTRL && vsi->vf) {
|
||||
ice_free_vf_ctrl_res(pf, vsi);
|
||||
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);
|
||||
|
||||
@@ -1310,3 +1310,35 @@ void ice_vf_set_initialized(struct ice_vf *vf)
|
||||
set_bit(ICE_VF_STATE_INIT, vf->vf_states);
|
||||
memset(&vf->vlan_v2_caps, 0, sizeof(vf->vlan_v2_caps));
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_get_vf_ctrl_vsi - Get first VF control VSI pointer
|
||||
* @pf: the PF private structure
|
||||
* @vsi: pointer to the VSI
|
||||
*
|
||||
* Return first found VF control VSI other than the vsi
|
||||
* passed by parameter. This function is used to determine
|
||||
* whether new resources have to be allocated for control VSI
|
||||
* or they can be shared with existing one.
|
||||
*
|
||||
* Return found VF control VSI pointer other itself. Return
|
||||
* NULL Otherwise.
|
||||
*
|
||||
*/
|
||||
struct ice_vsi *ice_get_vf_ctrl_vsi(struct ice_pf *pf, struct ice_vsi *vsi)
|
||||
{
|
||||
struct ice_vsi *ctrl_vsi = NULL;
|
||||
struct ice_vf *vf;
|
||||
unsigned int bkt;
|
||||
|
||||
rcu_read_lock();
|
||||
ice_for_each_vf_rcu(pf, bkt, vf) {
|
||||
if (vf != vsi->vf && vf->ctrl_vsi_idx != ICE_NO_VSI) {
|
||||
ctrl_vsi = pf->vsi[vf->ctrl_vsi_idx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
return ctrl_vsi;
|
||||
}
|
||||
|
||||
@@ -226,6 +226,7 @@ int
|
||||
ice_vf_clear_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m);
|
||||
int ice_reset_vf(struct ice_vf *vf, u32 flags);
|
||||
void ice_reset_all_vfs(struct ice_pf *pf);
|
||||
struct ice_vsi *ice_get_vf_ctrl_vsi(struct ice_pf *pf, struct ice_vsi *vsi);
|
||||
#else /* CONFIG_PCI_IOV */
|
||||
static inline struct ice_vf *ice_get_vf_by_id(struct ice_pf *pf, u16 vf_id)
|
||||
{
|
||||
@@ -290,6 +291,12 @@ static inline int ice_reset_vf(struct ice_vf *vf, u32 flags)
|
||||
static inline void ice_reset_all_vfs(struct ice_pf *pf)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct ice_vsi *
|
||||
ice_get_vf_ctrl_vsi(struct ice_pf *pf, struct ice_vsi *vsi)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* !CONFIG_PCI_IOV */
|
||||
|
||||
#endif /* _ICE_VF_LIB_H_ */
|
||||
|
||||
Reference in New Issue
Block a user