| From: Jacob Keller <jacob.e.keller@intel.com> |
| Date: Sat, 2 Mar 2013 07:51:42 +0000 |
| Subject: ixgbe: fix EICR write in ixgbe_msix_other |
| |
| commit d87d830720a1446403ed38bfc2da268be0d356d1 upstream. |
| |
| Previously, the ixgbe_msix_other was writing the full 32bits of the set |
| interrupts, instead of only the ones which the ixgbe_msix_other is |
| handling. This resulted in a loss of performance when the X540's PPS feature is |
| enabled due to sometimes clearing queue interrupts which resulted in the driver |
| not getting the interrupt for cleaning the q_vector rings often enough. The fix |
| is to simply mask the lower 16bits off so that this handler does not write them |
| in the EICR, which causes them to remain high and be properly handled by the |
| clean_rings interrupt routine as normal. |
| |
| Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> |
| Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> |
| Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 10 ++++++++++ |
| 1 file changed, 10 insertions(+) |
| |
| --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |
| +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |
| @@ -1937,6 +1937,16 @@ static irqreturn_t ixgbe_msix_other(int |
| * with the write to EICR. |
| */ |
| eicr = IXGBE_READ_REG(hw, IXGBE_EICS); |
| + |
| + /* The lower 16bits of the EICR register are for the queue interrupts |
| + * which should be masked here in order to not accidently clear them if |
| + * the bits are high when ixgbe_msix_other is called. There is a race |
| + * condition otherwise which results in possible performance loss |
| + * especially if the ixgbe_msix_other interrupt is triggering |
| + * consistently (as it would when PPS is turned on for the X540 device) |
| + */ |
| + eicr &= 0xFFFF0000; |
| + |
| IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr); |
| |
| if (eicr & IXGBE_EICR_LSC) |