@@ -1823,9 +1823,7 @@ static void ice_handle_mdd_event(struct ice_pf *pf)
* reset, so print the event prior to reset.
*/
ice_print_vf_rx_mdd_event(vf);
- mutex_lock(&vf->cfg_lock);
- ice_reset_vf(vf, 0);
- mutex_unlock(&vf->cfg_lock);
+ ice_reset_vf(vf, ICE_VF_RESET_LOCK);
}
}
}
@@ -1366,12 +1366,9 @@ void ice_process_vflr_event(struct ice_pf *pf)
bit_idx = (hw->func_caps.vf_base_id + vf->vf_id) % 32;
/* read GLGEN_VFLRSTAT register to find out the flr VFs */
reg = rd32(hw, GLGEN_VFLRSTAT(reg_idx));
- if (reg & BIT(bit_idx)) {
+ if (reg & BIT(bit_idx))
/* GLGEN_VFLRSTAT bit will be cleared in ice_reset_vf */
- mutex_lock(&vf->cfg_lock);
- ice_reset_vf(vf, ICE_VF_RESET_VFLR);
- mutex_unlock(&vf->cfg_lock);
- }
+ ice_reset_vf(vf, ICE_VF_RESET_VFLR | ICE_VF_RESET_LOCK);
}
mutex_unlock(&pf->vfs.table_lock);
}
@@ -1453,10 +1450,7 @@ ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event)
if (!vf)
return;
- mutex_lock(&vf->cfg_lock);
- ice_reset_vf(vf, ICE_VF_RESET_NOTIFY);
- mutex_unlock(&vf->cfg_lock);
-
+ ice_reset_vf(vf, ICE_VF_RESET_NOTIFY | ICE_VF_RESET_LOCK);
ice_put_vf(vf);
}
@@ -473,6 +473,7 @@ static void ice_notify_vf_reset(struct ice_vf *vf)
* Flags:
* ICE_VF_RESET_VFLR - Indicates a reset is due to VFLR event
* ICE_VF_RESET_NOTIFY - Send VF a notification prior to reset
+ * ICE_VF_RESET_LOCK - Acquire VF cfg_lock before resetting
*
* Returns 0 if the VF is currently in reset, if the resets are disabled, or
* if the VF resets successfully. Returns an error code if the VF fails to
@@ -485,10 +486,9 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
struct device *dev;
struct ice_hw *hw;
u8 promisc_m;
+ int err = 0;
bool rsd;
- lockdep_assert_held(&vf->cfg_lock);
-
dev = ice_pf_to_dev(pf);
hw = &pf->hw;
@@ -507,6 +507,11 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
return 0;
}
+ if (flags & ICE_VF_RESET_LOCK)
+ mutex_lock(&vf->cfg_lock);
+ else
+ lockdep_assert_held(&vf->cfg_lock);
+
/* Set VF disable bit state here, before triggering reset */
set_bit(ICE_VF_STATE_DIS, vf->vf_states);
ice_trigger_vf_reset(vf, flags & ICE_VF_RESET_VFLR, false);
@@ -564,7 +569,8 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
if (vf->vf_ops->vsi_rebuild(vf)) {
dev_err(dev, "Failed to release and setup the VF%u's VSI\n",
vf->vf_id);
- return -EFAULT;
+ err = -EFAULT;
+ goto out_unlock;
}
vf->vf_ops->post_vsi_rebuild(vf);
@@ -578,7 +584,11 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
dev_dbg(dev, "failed to clear malicious VF state for VF %u\n",
vf->vf_id);
- return 0;
+out_unlock:
+ if (flags & ICE_VF_RESET_LOCK)
+ mutex_unlock(&vf->cfg_lock);
+
+ return err;
}
/**
@@ -137,6 +137,7 @@ struct ice_vf {
enum ice_vf_reset_flags {
ICE_VF_RESET_VFLR = BIT(0), /* Indicate a VFLR reset */
ICE_VF_RESET_NOTIFY = BIT(1), /* Notify VF prior to reset */
+ ICE_VF_RESET_LOCK = BIT(2), /* Acquire the VF cfg_lock */
};
static inline u16 ice_vf_get_port_vlan_id(struct ice_vf *vf)