Commit d43d60e5 authored by Jacob Keller's avatar Jacob Keller Committed by Jeff Kirsher

i40e: ensure reset occurs when disabling VF

It is possible although rare that we may not reset when
i40e_vc_disable_vf() is called. This can lead to some weird
circumstances with some values not being properly set. Modify
i40e_reset_vf() to return a code indicating whether it reset or not.

Now, i40e_vc_disable_vf() can wait until a reset actually occurs. If it
fails to free up within a reasonable time frame we'll display a warning
message.
Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent f18d2021
...@@ -156,12 +156,28 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf) ...@@ -156,12 +156,28 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
* i40e_vc_disable_vf * i40e_vc_disable_vf
* @vf: pointer to the VF info * @vf: pointer to the VF info
* *
* Disable the VF through a SW reset * Disable the VF through a SW reset.
**/ **/
static inline void i40e_vc_disable_vf(struct i40e_vf *vf) static inline void i40e_vc_disable_vf(struct i40e_vf *vf)
{ {
int i;
i40e_vc_notify_vf_reset(vf); i40e_vc_notify_vf_reset(vf);
i40e_reset_vf(vf, false);
/* We want to ensure that an actual reset occurs initiated after this
* function was called. However, we do not want to wait forever, so
* we'll give a reasonable time and print a message if we failed to
* ensure a reset.
*/
for (i = 0; i < 20; i++) {
if (i40e_reset_vf(vf, false))
return;
usleep_range(10000, 20000);
}
dev_warn(&vf->pf->pdev->dev,
"Failed to initiate reset for VF %d after 200 milliseconds\n",
vf->vf_id);
} }
/** /**
...@@ -1051,9 +1067,9 @@ static void i40e_cleanup_reset_vf(struct i40e_vf *vf) ...@@ -1051,9 +1067,9 @@ static void i40e_cleanup_reset_vf(struct i40e_vf *vf)
* @vf: pointer to the VF structure * @vf: pointer to the VF structure
* @flr: VFLR was issued or not * @flr: VFLR was issued or not
* *
* reset the VF * Returns true if the VF is reset, false otherwise.
**/ **/
void i40e_reset_vf(struct i40e_vf *vf, bool flr) bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
{ {
struct i40e_pf *pf = vf->pf; struct i40e_pf *pf = vf->pf;
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
...@@ -1061,9 +1077,11 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr) ...@@ -1061,9 +1077,11 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
u32 reg; u32 reg;
int i; int i;
/* If VFs have been disabled, there is no need to reset */ /* If the VFs have been disabled, this means something else is
* resetting the VF, so we shouldn't continue.
*/
if (test_and_set_bit(__I40E_VF_DISABLE, pf->state)) if (test_and_set_bit(__I40E_VF_DISABLE, pf->state))
return; return false;
i40e_trigger_vf_reset(vf, flr); i40e_trigger_vf_reset(vf, flr);
...@@ -1100,6 +1118,8 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr) ...@@ -1100,6 +1118,8 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
i40e_flush(hw); i40e_flush(hw);
clear_bit(__I40E_VF_DISABLE, pf->state); clear_bit(__I40E_VF_DISABLE, pf->state);
return true;
} }
/** /**
...@@ -1111,8 +1131,10 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr) ...@@ -1111,8 +1131,10 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
* VF, then do all the waiting in one chunk, and finally finish restoring each * VF, then do all the waiting in one chunk, and finally finish restoring each
* VF after the wait. This is useful during PF routines which need to reset * VF after the wait. This is useful during PF routines which need to reset
* all VFs, as otherwise it must perform these resets in a serialized fashion. * all VFs, as otherwise it must perform these resets in a serialized fashion.
*
* Returns true if any VFs were reset, and false otherwise.
**/ **/
void i40e_reset_all_vfs(struct i40e_pf *pf, bool flr) bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
{ {
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
struct i40e_vf *vf; struct i40e_vf *vf;
...@@ -1121,11 +1143,11 @@ void i40e_reset_all_vfs(struct i40e_pf *pf, bool flr) ...@@ -1121,11 +1143,11 @@ void i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
/* If we don't have any VFs, then there is nothing to reset */ /* If we don't have any VFs, then there is nothing to reset */
if (!pf->num_alloc_vfs) if (!pf->num_alloc_vfs)
return; return false;
/* If VFs have been disabled, there is no need to reset */ /* If VFs have been disabled, there is no need to reset */
if (test_and_set_bit(__I40E_VF_DISABLE, pf->state)) if (test_and_set_bit(__I40E_VF_DISABLE, pf->state))
return; return false;
/* Begin reset on all VFs at once */ /* Begin reset on all VFs at once */
for (v = 0; v < pf->num_alloc_vfs; v++) for (v = 0; v < pf->num_alloc_vfs; v++)
...@@ -1200,6 +1222,8 @@ void i40e_reset_all_vfs(struct i40e_pf *pf, bool flr) ...@@ -1200,6 +1222,8 @@ void i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
i40e_flush(hw); i40e_flush(hw);
clear_bit(__I40E_VF_DISABLE, pf->state); clear_bit(__I40E_VF_DISABLE, pf->state);
return true;
} }
/** /**
......
...@@ -122,8 +122,8 @@ int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs); ...@@ -122,8 +122,8 @@ int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs);
int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode, int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode,
u32 v_retval, u8 *msg, u16 msglen); u32 v_retval, u8 *msg, u16 msglen);
int i40e_vc_process_vflr_event(struct i40e_pf *pf); int i40e_vc_process_vflr_event(struct i40e_pf *pf);
void i40e_reset_vf(struct i40e_vf *vf, bool flr); bool i40e_reset_vf(struct i40e_vf *vf, bool flr);
void i40e_reset_all_vfs(struct i40e_pf *pf, bool flr); bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr);
void i40e_vc_notify_vf_reset(struct i40e_vf *vf); void i40e_vc_notify_vf_reset(struct i40e_vf *vf);
/* VF configuration related iplink handlers */ /* VF configuration related iplink handlers */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment