i40e: rtnl_lock in reset path fixes
Any user-initiated path which eventually calls reset needs to hold the rtnl_lock, so add functionality to do that. Be careful not to use the safe reset when cleaning up from the diagnostic tests, which avoids rtnl_lock recursion from ethtool. Protect the reset_task with rtnl_lock, since it runs from a work item. Change-Id: Ib6e7a3fb2966809db2daf35fd5a123ccdf6f6f0f Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com> Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
4b7820ca4f
commit
233261867f
|
@ -502,6 +502,7 @@ int i40e_up(struct i40e_vsi *vsi);
|
|||
void i40e_down(struct i40e_vsi *vsi);
|
||||
extern const char i40e_driver_name[];
|
||||
extern const char i40e_driver_version_str[];
|
||||
void i40e_do_reset_safe(struct i40e_pf *pf, u32 reset_flags);
|
||||
void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags);
|
||||
void i40e_update_stats(struct i40e_vsi *vsi);
|
||||
void i40e_update_eth_stats(struct i40e_vsi *vsi);
|
||||
|
|
|
@ -1462,19 +1462,19 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
|
|||
}
|
||||
} else if (strncmp(cmd_buf, "pfr", 3) == 0) {
|
||||
dev_info(&pf->pdev->dev, "forcing PFR\n");
|
||||
i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
|
||||
i40e_do_reset_safe(pf, (1 << __I40E_PF_RESET_REQUESTED));
|
||||
|
||||
} else if (strncmp(cmd_buf, "corer", 5) == 0) {
|
||||
dev_info(&pf->pdev->dev, "forcing CoreR\n");
|
||||
i40e_do_reset(pf, (1 << __I40E_CORE_RESET_REQUESTED));
|
||||
i40e_do_reset_safe(pf, (1 << __I40E_CORE_RESET_REQUESTED));
|
||||
|
||||
} else if (strncmp(cmd_buf, "globr", 5) == 0) {
|
||||
dev_info(&pf->pdev->dev, "forcing GlobR\n");
|
||||
i40e_do_reset(pf, (1 << __I40E_GLOBAL_RESET_REQUESTED));
|
||||
i40e_do_reset_safe(pf, (1 << __I40E_GLOBAL_RESET_REQUESTED));
|
||||
|
||||
} else if (strncmp(cmd_buf, "empr", 4) == 0) {
|
||||
dev_info(&pf->pdev->dev, "forcing EMPR\n");
|
||||
i40e_do_reset(pf, (1 << __I40E_EMP_RESET_REQUESTED));
|
||||
i40e_do_reset_safe(pf, (1 << __I40E_EMP_RESET_REQUESTED));
|
||||
|
||||
} else if (strncmp(cmd_buf, "read", 4) == 0) {
|
||||
u32 address;
|
||||
|
|
|
@ -4131,6 +4131,19 @@ void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_do_reset_safe - Protected reset path for userland calls.
|
||||
* @pf: board private structure
|
||||
* @reset_flags: which reset is requested
|
||||
*
|
||||
**/
|
||||
void i40e_do_reset_safe(struct i40e_pf *pf, u32 reset_flags)
|
||||
{
|
||||
rtnl_lock();
|
||||
i40e_do_reset(pf, reset_flags);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_handle_lan_overflow_event - Handler for LAN queue overflow event
|
||||
* @pf: board private structure
|
||||
|
@ -4376,6 +4389,7 @@ static void i40e_reset_subtask(struct i40e_pf *pf)
|
|||
{
|
||||
u32 reset_flags = 0;
|
||||
|
||||
rtnl_lock();
|
||||
if (test_bit(__I40E_REINIT_REQUESTED, &pf->state)) {
|
||||
reset_flags |= (1 << __I40E_REINIT_REQUESTED);
|
||||
clear_bit(__I40E_REINIT_REQUESTED, &pf->state);
|
||||
|
@ -4398,7 +4412,7 @@ static void i40e_reset_subtask(struct i40e_pf *pf)
|
|||
*/
|
||||
if (test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state)) {
|
||||
i40e_handle_reset_warning(pf);
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* If we're already down or resetting, just bail */
|
||||
|
@ -4406,6 +4420,9 @@ static void i40e_reset_subtask(struct i40e_pf *pf)
|
|||
!test_bit(__I40E_DOWN, &pf->state) &&
|
||||
!test_bit(__I40E_CONFIG_BUSY, &pf->state))
|
||||
i40e_do_reset(pf, reset_flags);
|
||||
|
||||
unlock:
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue