* [net 0/2][pull request] Intel Wired LAN Driver Updates 2017-09-05
@ 2017-09-06 1:04 Jeff Kirsher
2017-09-06 1:04 ` [net 1/2] i40e: avoid NVM acquire deadlock during NVM update Jeff Kirsher
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Jeff Kirsher @ 2017-09-06 1:04 UTC (permalink / raw)
To: davem; +Cc: Jeff Kirsher, netdev, nhorman, sassmann, jogreene
This series contains fixes for i40e only.
These two patches fix an issue where our nvmupdate tool does not work on RHEL 7.4
and newer kernels, in fact, the use of the nvmupdate tool on newer kernels can
cause the cards to be non-functional unless these patches are applied.
Anjali reworks the locking around accessing the NVM so that NVM acquire timeouts
do not occur which was causing the failed firmware updates.
Jake correctly updates the wb_desc when reading the NVM through the AdminQ.
The following are changes since commit 6d9c153a0b84392406bc77600aa7d3ea365de041:
net: dsa: loop: Do not unregister invalid fixed PHY
and are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue 40GbE
Anjali Singhai Jain (1):
i40e: avoid NVM acquire deadlock during NVM update
Jacob Keller (1):
i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq
drivers/net/ethernet/intel/i40e/i40e_nvm.c | 99 +++++++++++++++---------
drivers/net/ethernet/intel/i40e/i40e_prototype.h | 2 -
2 files changed, 61 insertions(+), 40 deletions(-)
--
2.14.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [net 1/2] i40e: avoid NVM acquire deadlock during NVM update
2017-09-06 1:04 [net 0/2][pull request] Intel Wired LAN Driver Updates 2017-09-05 Jeff Kirsher
@ 2017-09-06 1:04 ` Jeff Kirsher
2017-09-06 1:04 ` [net 2/2] i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq Jeff Kirsher
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Jeff Kirsher @ 2017-09-06 1:04 UTC (permalink / raw)
To: davem
Cc: Anjali Singhai Jain, netdev, nhorman, sassmann, jogreene,
Jacob Keller, Jeff Kirsher
From: Anjali Singhai Jain <anjali.singhai@intel.com>
X722 devices use the AdminQ to access the NVM, and this requires taking
the AdminQ lock. Because of this, we lock the AdminQ during
i40e_read_nvm(), which is also called in places where the lock is
already held, such as the firmware update path which wants to lock once
and then unlock when finished after performing several tasks.
Although this should have only affected X722 devices, commit
96a39aed25e6 ("i40e: Acquire NVM lock before reads on all devices",
2016-12-02) added locking for all NVM reads, regardless of device
family.
This resulted in us accidentally causing NVM acquire timeouts on all
devices, causing failed firmware updates which left the eeprom in
a corrupt state.
Create unsafe non-locked variants of i40e_read_nvm_word and
i40e_read_nvm_buffer, __i40e_read_nvm_word and __i40e_read_nvm_buffer
respectively. These variants will not take the NVM lock and are expected
to only be called in places where the NVM lock is already held if
needed.
Since the only caller of i40e_read_nvm_buffer() was in such a path,
remove it entirely in favor of the unsafe version. If necessary we can
always add it back in the future.
Additionally, we now need to hold the NVM lock in i40e_validate_checksum
because the call to i40e_calc_nvm_checksum now assumes that the NVM lock
is held. We can further move the call to read I40E_SR_SW_CHECKSUM_WORD
up a bit so that we do not need to acquire the NVM lock twice.
This should resolve firmware updates and also fix potential raise that
could have caused the driver to report an invalid NVM checksum upon
driver load.
Reported-by: Stefan Assmann <sassmann@kpanic.de>
Fixes: 96a39aed25e6 ("i40e: Acquire NVM lock before reads on all devices", 2016-12-02)
Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_nvm.c | 98 +++++++++++++++---------
drivers/net/ethernet/intel/i40e/i40e_prototype.h | 2 -
2 files changed, 60 insertions(+), 40 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 800bd55d0159..154ba49c2c6f 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -266,7 +266,7 @@ static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
* @data: word read from the Shadow RAM
*
- * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
+ * Reads one 16 bit word from the Shadow RAM using the AdminQ
**/
static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
u16 *data)
@@ -280,27 +280,49 @@ static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
}
/**
- * i40e_read_nvm_word - Reads Shadow RAM
+ * __i40e_read_nvm_word - Reads nvm word, assumes called does the locking
* @hw: pointer to the HW structure
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
* @data: word read from the Shadow RAM
*
- * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
+ * Reads one 16 bit word from the Shadow RAM.
+ *
+ * Do not use this function except in cases where the nvm lock is already
+ * taken via i40e_acquire_nvm().
+ **/
+static i40e_status __i40e_read_nvm_word(struct i40e_hw *hw,
+ u16 offset, u16 *data)
+{
+ i40e_status ret_code = 0;
+
+ if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
+ ret_code = i40e_read_nvm_word_aq(hw, offset, data);
+ else
+ ret_code = i40e_read_nvm_word_srctl(hw, offset, data);
+ return ret_code;
+}
+
+/**
+ * i40e_read_nvm_word - Reads nvm word and acquire lock if necessary
+ * @hw: pointer to the HW structure
+ * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
+ * @data: word read from the Shadow RAM
+ *
+ * Reads one 16 bit word from the Shadow RAM.
**/
i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
u16 *data)
{
- enum i40e_status_code ret_code = 0;
+ i40e_status ret_code = 0;
ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
- if (!ret_code) {
- if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) {
- ret_code = i40e_read_nvm_word_aq(hw, offset, data);
- } else {
- ret_code = i40e_read_nvm_word_srctl(hw, offset, data);
- }
- i40e_release_nvm(hw);
- }
+ if (ret_code)
+ return ret_code;
+
+ ret_code = __i40e_read_nvm_word(hw, offset, data);
+
+ i40e_release_nvm(hw);
+
return ret_code;
}
@@ -393,31 +415,25 @@ static i40e_status i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
}
/**
- * i40e_read_nvm_buffer - Reads Shadow RAM buffer
+ * __i40e_read_nvm_buffer - Reads nvm buffer, caller must acquire lock
* @hw: pointer to the HW structure
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
* @words: (in) number of words to read; (out) number of words actually read
* @data: words read from the Shadow RAM
*
* Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
- * method. The buffer read is preceded by the NVM ownership take
- * and followed by the release.
+ * method.
**/
-i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
- u16 *words, u16 *data)
+static i40e_status __i40e_read_nvm_buffer(struct i40e_hw *hw,
+ u16 offset, u16 *words,
+ u16 *data)
{
- enum i40e_status_code ret_code = 0;
+ i40e_status ret_code = 0;
- if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) {
- ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
- if (!ret_code) {
- ret_code = i40e_read_nvm_buffer_aq(hw, offset, words,
- data);
- i40e_release_nvm(hw);
- }
- } else {
+ if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
+ ret_code = i40e_read_nvm_buffer_aq(hw, offset, words, data);
+ else
ret_code = i40e_read_nvm_buffer_srctl(hw, offset, words, data);
- }
return ret_code;
}
@@ -499,15 +515,15 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
data = (u16 *)vmem.va;
/* read pointer to VPD area */
- ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
+ ret_code = __i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
if (ret_code) {
ret_code = I40E_ERR_NVM_CHECKSUM;
goto i40e_calc_nvm_checksum_exit;
}
/* read pointer to PCIe Alt Auto-load module */
- ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
- &pcie_alt_module);
+ ret_code = __i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
+ &pcie_alt_module);
if (ret_code) {
ret_code = I40E_ERR_NVM_CHECKSUM;
goto i40e_calc_nvm_checksum_exit;
@@ -521,7 +537,7 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) {
u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS;
- ret_code = i40e_read_nvm_buffer(hw, i, &words, data);
+ ret_code = __i40e_read_nvm_buffer(hw, i, &words, data);
if (ret_code) {
ret_code = I40E_ERR_NVM_CHECKSUM;
goto i40e_calc_nvm_checksum_exit;
@@ -593,14 +609,19 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
u16 checksum_sr = 0;
u16 checksum_local = 0;
+ /* We must acquire the NVM lock in order to correctly synchronize the
+ * NVM accesses across multiple PFs. Without doing so it is possible
+ * for one of the PFs to read invalid data potentially indicating that
+ * the checksum is invalid.
+ */
+ ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
+ if (ret_code)
+ return ret_code;
ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
+ __i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
+ i40e_release_nvm(hw);
if (ret_code)
- goto i40e_validate_nvm_checksum_exit;
-
- /* Do not use i40e_read_nvm_word() because we do not want to take
- * the synchronization semaphores twice here.
- */
- i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
+ return ret_code;
/* Verify read checksum from EEPROM is the same as
* calculated checksum
@@ -612,7 +633,6 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
if (checksum)
*checksum = checksum_local;
-i40e_validate_nvm_checksum_exit:
return ret_code;
}
@@ -997,6 +1017,7 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
break;
case I40E_NVMUPD_CSUM_CON:
+ /* Assumes the caller has acquired the nvm */
status = i40e_update_nvm_checksum(hw);
if (status) {
*perrno = hw->aq.asq_last_status ?
@@ -1011,6 +1032,7 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
break;
case I40E_NVMUPD_CSUM_LCB:
+ /* Assumes the caller has acquired the nvm */
status = i40e_update_nvm_checksum(hw);
if (status) {
*perrno = hw->aq.asq_last_status ?
diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
index df613ea40313..a39b13197891 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
@@ -311,8 +311,6 @@ i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
void i40e_release_nvm(struct i40e_hw *hw);
i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
u16 *data);
-i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
- u16 *words, u16 *data);
i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw);
i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
u16 *checksum);
--
2.14.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [net 2/2] i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq
2017-09-06 1:04 [net 0/2][pull request] Intel Wired LAN Driver Updates 2017-09-05 Jeff Kirsher
2017-09-06 1:04 ` [net 1/2] i40e: avoid NVM acquire deadlock during NVM update Jeff Kirsher
@ 2017-09-06 1:04 ` Jeff Kirsher
2017-09-06 3:03 ` [net 0/2][pull request] Intel Wired LAN Driver Updates 2017-09-05 David Miller
2017-09-06 10:55 ` Stefano Brivio
3 siblings, 0 replies; 5+ messages in thread
From: Jeff Kirsher @ 2017-09-06 1:04 UTC (permalink / raw)
To: davem; +Cc: Jacob Keller, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
From: Jacob Keller <jacob.e.keller@intel.com>
When introducing the functions to read the NVM through the AdminQ, we
did not correctly mark the wb_desc.
Fixes: 7073f46e443e ("i40e: Add AQ commands for NVM Update for X722", 2015-06-05)
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_nvm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 154ba49c2c6f..26d7e9fe6220 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -230,6 +230,7 @@ static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
struct i40e_asq_cmd_details cmd_details;
memset(&cmd_details, 0, sizeof(cmd_details));
+ cmd_details.wb_desc = &hw->nvm_wb_desc;
/* Here we are checking the SR limit only for the flat memory model.
* We cannot do it for the module-based model, as we did not acquire
--
2.14.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [net 0/2][pull request] Intel Wired LAN Driver Updates 2017-09-05
2017-09-06 1:04 [net 0/2][pull request] Intel Wired LAN Driver Updates 2017-09-05 Jeff Kirsher
2017-09-06 1:04 ` [net 1/2] i40e: avoid NVM acquire deadlock during NVM update Jeff Kirsher
2017-09-06 1:04 ` [net 2/2] i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq Jeff Kirsher
@ 2017-09-06 3:03 ` David Miller
2017-09-06 10:55 ` Stefano Brivio
3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2017-09-06 3:03 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: netdev, nhorman, sassmann, jogreene
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Tue, 5 Sep 2017 18:04:16 -0700
> This series contains fixes for i40e only.
Pulled, thanks Jeff.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [net 0/2][pull request] Intel Wired LAN Driver Updates 2017-09-05
2017-09-06 1:04 [net 0/2][pull request] Intel Wired LAN Driver Updates 2017-09-05 Jeff Kirsher
` (2 preceding siblings ...)
2017-09-06 3:03 ` [net 0/2][pull request] Intel Wired LAN Driver Updates 2017-09-05 David Miller
@ 2017-09-06 10:55 ` Stefano Brivio
3 siblings, 0 replies; 5+ messages in thread
From: Stefano Brivio @ 2017-09-06 10:55 UTC (permalink / raw)
To: davem; +Cc: Jeff Kirsher, netdev, nhorman, sassmann, jogreene
On Tue, 5 Sep 2017 18:04:16 -0700
Jeff Kirsher <jeffrey.t.kirsher@intel.com> wrote:
> This series contains fixes for i40e only.
>
> These two patches fix an issue where our nvmupdate tool does not work on RHEL 7.4
> and newer kernels, in fact, the use of the nvmupdate tool on newer kernels can
> cause the cards to be non-functional unless these patches are applied.
>
> Anjali reworks the locking around accessing the NVM so that NVM acquire timeouts
> do not occur which was causing the failed firmware updates.
>
> Jake correctly updates the wb_desc when reading the NVM through the AdminQ.
>
> The following are changes since commit 6d9c153a0b84392406bc77600aa7d3ea365de041:
> net: dsa: loop: Do not unregister invalid fixed PHY
> and are available in the git repository at:
> git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue 40GbE
>
> Anjali Singhai Jain (1):
> i40e: avoid NVM acquire deadlock during NVM update
>
> Jacob Keller (1):
> i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq
I think this should go to -stable too (4.12+), as cards completely
stop working after a firmware upgrade.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-09-06 10:55 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-06 1:04 [net 0/2][pull request] Intel Wired LAN Driver Updates 2017-09-05 Jeff Kirsher
2017-09-06 1:04 ` [net 1/2] i40e: avoid NVM acquire deadlock during NVM update Jeff Kirsher
2017-09-06 1:04 ` [net 2/2] i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq Jeff Kirsher
2017-09-06 3:03 ` [net 0/2][pull request] Intel Wired LAN Driver Updates 2017-09-05 David Miller
2017-09-06 10:55 ` Stefano Brivio
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).