aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSudheer Mogilappagari <sudheer.mogilappagari@intel.com>2017-07-12 05:46:07 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2017-08-25 14:52:52 -0700
commit2bf01935ec5362aee6ff9ffc2476043af321aa42 (patch)
treeccd7653782c567b8b8a0762ffc3fae379a249737
parenti40e: prevent changing ITR if adaptive-rx/tx enabled (diff)
downloadlinux-dev-2bf01935ec5362aee6ff9ffc2476043af321aa42.tar.xz
linux-dev-2bf01935ec5362aee6ff9ffc2476043af321aa42.zip
i40e: synchronize nvmupdate command and adminq subtask
During NVM update, state machine gets into unrecoverable state because i40e_clean_adminq_subtask can get scheduled after the admin queue command but before other state variables are updated. This causes incorrect input to i40e_nvmupd_check_wait_event and state transitions don't happen. This issue existed before but surfaced after commit 373149fc99a0 ("i40e: Decrease the scope of rtnl lock") This fix adds locking around admin queue command and update of state variables so that adminq_subtask will have accurate information whenever it gets scheduled. Signed-off-by: Sudheer Mogilappagari <sudheer.mogilappagari@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_nvm.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 6fdecd70dcbc..2cf7db2dc7cd 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -753,6 +753,11 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
}
+ /* Acquire lock to prevent race condition where adminq_task
+ * can execute after i40e_nvmupd_nvm_read/write but before state
+ * variables (nvm_wait_opcode, nvm_release_on_done) are updated
+ */
+ mutex_lock(&hw->aq.arq_mutex);
switch (hw->nvmupd_state) {
case I40E_NVMUPD_STATE_INIT:
status = i40e_nvmupd_state_init(hw, cmd, bytes, perrno);
@@ -788,6 +793,7 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
*perrno = -ESRCH;
break;
}
+ mutex_unlock(&hw->aq.arq_mutex);
return status;
}