From: Aaron Brown <hidden> Date: 2014-01-08 07:40:10
This series contains add Live Error Recovery (LER) support to the ixgbe
driver. This support also improves behavior in Thunderbolt environments.
This involves checking all register reads for a value of all ones and when
that is seen, to read the status register, which should never properly
return all ones, to confirm whether the received value was correct. When
this detects a removal, the hw_addr field is cleared to indicate the
removal. This then blocks subsequent access to the device registers.
All register access macros have been changed to static inline functions
and all register accesses now use them.
The __IXGBE_DOWN bit is no longer overloaded to also mean that device
removal has been initiated. Now the bit can be used to protect ixgbe_down
from multiple entry via test_and_set_bit. A needed smp_mb__before_clear_bit
was also added.
Mark Rustad (7):
1/7 ixbge: Protect ixgbe_down with __IXGBE_DOWN bit
2/7 ixgbe: Indicate removal state explicitly
3/7 ixgbe: Use static inlines instead of macros
4/7 ixgbe: Make ethtool register test use accessors
5/7 ixgbe: Check register reads for adapter removal
6/7 ixgbe: Check for adapter removal on register writes
7/7 ixgbe: Additional adapter removal checks
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 7 ++
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h | 55 +++++++++---
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 110 +++++++++++++----------
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 74 ++++++++++++---
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c | 3 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 2 +-
6 files changed, 180 insertions(+), 71 deletions(-)
--
1.8.5.GIT
From: Aaron Brown <hidden> Date: 2014-01-08 07:40:11
From: Mark Rustad <redacted>
The ixgbe_down function can now prevent multiple executions by
doing test_and_set_bit on __IXGBE_DOWN. This did not work before
introduction of the __IXGBE_REMOVED bit, because of overloading
of __IXGBE_DOWN. Also add smp_mb__before_clear_bit call before
clearing the __IXGBE_DOWN bit.
Signed-off-by: Mark Rustad <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Aaron Brown <redacted>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
@@ -4783,7 +4784,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)inti;/* signal that we are down to the interrupt handler */-set_bit(__IXGBE_DOWN,&adapter->state);+if(test_and_set_bit(__IXGBE_DOWN,&adapter->state))+return;/* do nothing if already down *//* disable receives */rxctrl=IXGBE_READ_REG(hw,IXGBE_RXCTRL);
From: Aaron Brown <hidden> Date: 2014-01-08 07:40:12
From: Mark Rustad <redacted>
Add a bit, __IXGBE_REMOVE, to indicate that the module is being
removed. The __IXGBE_DOWN bit had been overloaded for this purpose,
but that leads to trouble. A few places now check both __IXGBE_DOWN
and __IXGBE_REMOVE. Notably, setting either bit will prevent service
task execution.
Signed-off-by: Mark Rustad <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Aaron Brown <redacted>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 12 ++++++++----
2 files changed, 9 insertions(+), 4 deletions(-)
@@ -5876,8 +5877,9 @@ static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter)u64eics=0;inti;-/* If we're down or resetting, just bail */+/* If we're down, removing or resetting, just bail */if(test_bit(__IXGBE_DOWN,&adapter->state)||+test_bit(__IXGBE_REMOVE,&adapter->state)||test_bit(__IXGBE_RESETTING,&adapter->state))return;
@@ -6124,8 +6126,9 @@ static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)**/staticvoidixgbe_watchdog_subtask(structixgbe_adapter*adapter){-/* if interface is down do nothing */+/* if interface is down, removing or resetting, do nothing */if(test_bit(__IXGBE_DOWN,&adapter->state)||+test_bit(__IXGBE_REMOVE,&adapter->state)||test_bit(__IXGBE_RESETTING,&adapter->state))return;
@@ -6343,8 +6346,9 @@ static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)adapter->flags2&=~IXGBE_FLAG2_RESET_REQUESTED;-/* If we're already down or resetting, just bail */+/* If we're already down, removing or resetting, just bail */if(test_bit(__IXGBE_DOWN,&adapter->state)||+test_bit(__IXGBE_REMOVE,&adapter->state)||test_bit(__IXGBE_RESETTING,&adapter->state))return;
From: Aaron Brown <hidden> Date: 2014-01-08 07:40:12
From: Mark Rustad <redacted>
Kernel coding standard prefers static inline functions instead
of macros, so use them for register accessors. This is to prepare
for adding LER, Live Error Recovery, checks to those accessors.
Signed-off-by: Mark Rustad <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Aaron Brown <redacted>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 5 +++++
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h | 30 +++++++++++++++++--------
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 ++--
3 files changed, 28 insertions(+), 11 deletions(-)
From: Aaron Brown <hidden> Date: 2014-01-08 07:40:13
From: Mark Rustad <redacted>
Make the ethtool register test use the normal register accessor
functions. Also eliminate macros used for calling register test
functions to make error exits clearer. Use boolean values for
boolean returns instead of 0 and 1.
Signed-off-by: Mark Rustad <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Aaron Brown <redacted>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 88 +++++++++++-------------
1 file changed, 42 insertions(+), 46 deletions(-)
From: Aaron Brown <hidden> Date: 2014-01-08 07:40:17
From: Mark Rustad <redacted>
Check all register reads for adapter removal by checking the status
register after any register read that returns 0xFFFFFFFF. Since the
status register will never return 0xFFFFFFFF unless the adapter is
removed, such a value from a status register read confirms the
removal.
Signed-off-by: Mark Rustad <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Aaron Brown <redacted>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h | 15 +++++++++-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 38 ++++++++++++++++++++++---
3 files changed, 49 insertions(+), 5 deletions(-)
@@ -283,6 +283,35 @@ static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)schedule_work(&adapter->service_task);}+staticvoidixgbe_remove_adapter(structixgbe_hw*hw)+{+structixgbe_adapter*adapter=hw->back;++if(!hw->hw_addr)+return;+hw->hw_addr=NULL;+e_dev_err("Adapter removed\n");+}++voidixgbe_check_remove(structixgbe_hw*hw,u32reg)+{+u32value;++/* The following check not only optimizes a bit by not+*performingareadonthestatusregisterwhenthe+*registerjustreadwasastatusregisterreadthat+*returnedIXGBE_FAILED_READ_REG.Italsoblocksany+*potentialrecursion.+*/+if(reg==IXGBE_STATUS){+ixgbe_remove_adapter(hw);+return;+}+value=IXGBE_READ_REG(hw,IXGBE_STATUS);+if(value==IXGBE_FAILED_READ_REG)+ixgbe_remove_adapter(hw);+}+staticvoidixgbe_service_event_complete(structixgbe_adapter*adapter){BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED,&adapter->state));
From: Aaron Brown <hidden> Date: 2014-01-08 07:40:17
From: Mark Rustad <redacted>
Prevent writes to an adapter that has been detected as removed
by a previous failing read. This also fixes some include file
ordering confusion that this patch revealed.
Signed-off-by: Mark Rustad <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Aaron Brown <redacted>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h | 12 ++++++++++--
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c | 3 +--
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 2 +-
3 files changed, 12 insertions(+), 5 deletions(-)
From: Aaron Brown <hidden> Date: 2014-01-08 07:40:18
From: Mark Rustad <redacted>
Additional checks are needed for a detected removal not to cause
problems. Some involve simply avoiding a lot of stuff that can't
do anything good, and also cases where the phony return value can
cause problems. In addition, down the adapter when the removal is
sensed.
Signed-off-by: Mark Rustad <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Aaron Brown <redacted>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 22 ++++++++++++++++++++++
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 16 ++++++++++++++++
2 files changed, 38 insertions(+)
@@ -3338,6 +3339,8 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,u32rxdctl;u8reg_idx=ring->reg_idx;+if(IXGBE_REMOVED(hw->hw_addr))+return;/* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */if(hw->mac.type==ixgbe_mac_82598EB&&!(IXGBE_READ_REG(hw,IXGBE_LINKS)&IXGBE_LINKS_UP))
@@ -4687,6 +4692,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)structixgbe_hw*hw=&adapter->hw;interr;+if(IXGBE_REMOVED(hw->hw_addr))+return;/* lock SFP init bit to prevent race conditions with the watchdog */while(test_and_set_bit(__IXGBE_IN_SFP_INIT,&adapter->state))usleep_range(1000,2000);
schedule_work(&adapter->service_task);
}
+static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
+{
+ struct ixgbe_adapter *adapter = hw->back;
+
+ if (!hw->hw_addr)
+ return;
+ hw->hw_addr = NULL;
+ e_dev_err("Adapter removed\n");
+}
+
+void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
+{
+ u32 value;
+
+ /* The following check not only optimizes a bit by not
+ * performing a read on the status register when the
+ * register just read was a status register read that
+ * returned IXGBE_FAILED_READ_REG. It also blocks any
+ * potential recursion.
+ */
+ if (reg == IXGBE_STATUS) {
+ ixgbe_remove_adapter(hw);
+ return;
+ }
+ value = IXGBE_READ_REG(hw, IXGBE_STATUS);
+ if (value == IXGBE_FAILED_READ_REG)
+ ixgbe_remove_adapter(hw);
+}
+
static void ixgbe_service_event_complete(struct ixgbe_adapter *adapter)
{
BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED, &adapter->state));
kfree(adapter->ixgbe_ieee_ets);
#endif
- iounmap(adapter->hw.hw_addr);
+ iounmap(adapter->io_addr);
pci_release_selected_regions(pdev, pci_select_bars(pdev,
IORESOURCE_MEM));
--
1.8.5.GIT
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Scott Feldman <hidden> Date: 2014-01-08 08:37:25
On Jan 7, 2014, at 11:40 PM, Aaron Brown [off-list ref] wrote:
quoted hunk
From: Mark Rustad <redacted>
Add a bit, __IXGBE_REMOVE, to indicate that the module is being
removed. The __IXGBE_DOWN bit had been overloaded for this purpose,
but that leads to trouble. A few places now check both __IXGBE_DOWN
and __IXGBE_REMOVE. Notably, setting either bit will prevent service
task execution.
Signed-off-by: Mark Rustad <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Aaron Brown <redacted>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 12 ++++++++----
2 files changed, 9 insertions(+), 4 deletions(-)
How is this related to the commit msg about register reads? Seems like two patches.
No, it is theoretically possible for hw_addr to be NULL now if a removal was somehow detected, so using the new io_addr that will never be NULL is safer. The possibility of hw_addr being NULL is introduced by these patches, so this change should be a part of these patches.
<snip>
Sorry for the duplicate Scott. You may have noticed that I failed to copy everyone else as I should have.
--
Mark Rustad, Networking Division, Intel Corporation
From: Rustad, Mark D <hidden> Date: 2014-01-09 17:29:31
On Jan 8, 2014, at 12:37 AM, Scott Feldman [off-list ref] wrote:
On Jan 7, 2014, at 11:40 PM, Aaron Brown [off-list ref] wrote:
quoted
From: Mark Rustad <redacted>
Add a bit, __IXGBE_REMOVE, to indicate that the module is being
removed. The __IXGBE_DOWN bit had been overloaded for this purpose,
but that leads to trouble. A few places now check both __IXGBE_DOWN
and __IXGBE_REMOVE. Notably, setting either bit will prevent service
task execution.
Signed-off-by: Mark Rustad <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Aaron Brown <redacted>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 12 ++++++++----
2 files changed, 9 insertions(+), 4 deletions(-)
Agreed, but this is actually a fairly common condition among drivers that used to use macros. It isn't perfect, but at least it is moving in the right direction. I'd rather leave the case change for a later patch series that does only that or has some reason to touch all of the register access sites.
At least the new accessor I introduced is lower case. :-)
--
Mark Rustad, Networking Division, Intel Corporation
IXGBE_REMOVED seems pretty closely tied to hw->hw_addr, but the macro turns any input into !input. Maybe an inline that takes a *hw?
An earlier version had two different inputs, but not any more. I will change it to take a hw parameter. Good suggestion.
Actually, I responded too quickly. Although my comment on there previously having been two different inputs was true, that isn't the real reason for this form. The reason is that the check needs to be done on the value retrieved by ACCESS_ONCE - the address that will be used for the access. If the parameter were hw, then a separate dereference could occur, which is definitely not wanted.
One could argue that the macro should just be eliminated and the expansion put everywhere, but I feel that the code is much clearer with the macro. Unless there is another suggestion, I think this should stay as it is in this series.
--
Mark Rustad, Networking Division, Intel Corporation
Agreed, but this is actually a fairly common condition among drivers that used to use macros. It isn't perfect, but at least it is moving in the right direction. I'd rather leave the case change for a later patch series that does only that or has some reason to touch all of the register access sites.
At least the new accessor I introduced is lower case. :-)
Please address this feedback, all caps function names are really not
appropriate.
Agreed, but this is actually a fairly common condition among drivers that used to use macros. It isn't perfect, but at least it is moving in the right direction. I'd rather leave the case change for a later patch series that does only that or has some reason to touch all of the register access sites.
At least the new accessor I introduced is lower case. :-)
Please address this feedback, all caps function names are really not
appropriate.
I really don't think it is a good idea to do that as part of this patch series. It makes this patch series a pretty solid barrier to any other patches going into this driver because it would change the name of all the register accessors.
This makes me want to deal with that as a separate issue, since there would be no functional reason to drop such a patch and it can be planned into a workflow.
Obviously I could do it here, but I *really* think it is procedurally a really bad idea to change the case as part of a functional change. I thought I was doing a favor my at least making them inlines, but prehaps not.
Anyone want to take on changing the upper case static inlines in mcf8390, 7990, benet, ns83820, s2io, vxge, iwlwifi, ath9k, wil6210, mwifiex, and rtlwifi? And those are just under drivers/net.
--
Mark Rustad, Networking Division, Intel Corporation
From: David Miller <davem@davemloft.net> Date: 2014-01-09 20:20:00
From: "Rustad, Mark D" <redacted>
Date: Thu, 9 Jan 2014 20:14:51 +0000
Obviously I could do it here, but I *really* think it is
procedurally a really bad idea to change the case as part of a
functional change. I thought I was doing a favor my at least making
them inlines, but prehaps not.
It is never a good idea to allow functions to have all caps
names and vice versa. Please don't use "difficulty" as a reason
to violate this.
Doing things right is sometimes hard, I'm sorry to inform you :)
Anyone want to take on changing the upper case static inlines in
mcf8390, 7990, benet, ns83820, s2io, vxge, iwlwifi, ath9k, wil6210,
mwifiex, and rtlwifi? And those are just under drivers/net.
Sorry the "crap exists elsewhere, therefore I can make crap too"
argument never holds any water.
Just because crap exists elsewhere, doesn't mean you should duplicate it.
From: Rustad, Mark D <hidden> Date: 2014-01-09 20:46:35
On Jan 9, 2014, at 12:19 PM, David Miller [off-list ref] wrote:
From: "Rustad, Mark D" <redacted>
Date: Thu, 9 Jan 2014 20:14:51 +0000
I'm sorry you dropped my entire procedural argument for not combining the changing of the case with the implementation of the static inlines. That really was and is important! I'm not opposed to changing the case. My concern is for procedurally when and how it gets done.
quoted
Obviously I could do it here, but I *really* think it is
procedurally a really bad idea to change the case as part of a
functional change. I thought I was doing a favor my at least making
them inlines, but prehaps not.
It is never a good idea to allow functions to have all caps
names and vice versa. Please don't use "difficulty" as a reason
to violate this.
Doing things right is sometimes hard, I'm sorry to inform you :)
It is just that sometimes things take multiple steps. This was just one step. I'm sorry that I may have not made that clear enough. Doing the work is absolutely not the problem, managing the process so everyone can continue working is a concern.
quoted
Anyone want to take on changing the upper case static inlines in
mcf8390, 7990, benet, ns83820, s2io, vxge, iwlwifi, ath9k, wil6210,
mwifiex, and rtlwifi? And those are just under drivers/net.
Sorry the "crap exists elsewhere, therefore I can make crap too"
argument never holds any water.
Just because crap exists elsewhere, doesn't mean you should duplicate it.
I'm sorry that the presence misled me into thinking that it was acceptable at least in a transitional phase.
I think I have found a way to address the barrier issue. I will add upper case macros that call the lower case inlines, so for a time both forms may exist, and then have a patch that will update the call sites, and then a patch to remove the macros.
Is that acceptable?
If only one person were working in this area and everything were serial, it would be much easier to manage this kind of change. When that is not the case, it is better for things to happen in separate steps.
--
Mark Rustad, Networking Division, Intel Corporation
From: David Miller <davem@davemloft.net> Date: 2014-01-09 20:59:30
From: "Rustad, Mark D" <redacted>
Date: Thu, 9 Jan 2014 20:46:33 +0000
I think I have found a way to address the barrier issue. I will add
upper case macros that call the lower case inlines, so for a time
both forms may exist, and then have a patch that will update the
call sites, and then a patch to remove the macros.
Is that acceptable?