aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Rose <gregory.v.rose@intel.com>2012-01-18 17:13:31 -0500
committerDavid S. Miller <davem@davemloft.net>2012-01-19 12:35:06 -0500
commit375b27cf5db963e2bc2a34dc5643d0d7ceca1ee2 (patch)
tree5448047154a5c4676685f8665d8af6b96647d68b
parent795be954dcc4a72329c8591aafe5eadb03b264af (diff)
ixgbevf: Prevent possible race condition by checking for message
The mailbox interrupt routine might cause a race condition sometimes and cause a message to be missed. Signed-off-by: Greg Rose <gregory.v.rose@intel.com> Tested-by: Sibai Li <sibai.li@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 891162d1610c..1cad3b6d2c30 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -917,31 +917,34 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
917 struct ixgbe_hw *hw = &adapter->hw; 917 struct ixgbe_hw *hw = &adapter->hw;
918 u32 eicr; 918 u32 eicr;
919 u32 msg; 919 u32 msg;
920 bool got_ack = false;
920 921
921 eicr = IXGBE_READ_REG(hw, IXGBE_VTEICS); 922 eicr = IXGBE_READ_REG(hw, IXGBE_VTEICS);
922 IXGBE_WRITE_REG(hw, IXGBE_VTEICR, eicr); 923 IXGBE_WRITE_REG(hw, IXGBE_VTEICR, eicr);
923 924
924 if (!hw->mbx.ops.check_for_ack(hw)) { 925 if (!hw->mbx.ops.check_for_ack(hw))
925 /* 926 got_ack = true;
926 * checking for the ack clears the PFACK bit. Place
927 * it back in the v2p_mailbox cache so that anyone
928 * polling for an ack will not miss it. Also
929 * avoid the read below because the code to read
930 * the mailbox will also clear the ack bit. This was
931 * causing lost acks. Just cache the bit and exit
932 * the IRQ handler.
933 */
934 hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
935 goto out;
936 }
937 927
938 /* Not an ack interrupt, go ahead and read the message */ 928 if (!hw->mbx.ops.check_for_msg(hw)) {
939 hw->mbx.ops.read(hw, &msg, 1); 929 hw->mbx.ops.read(hw, &msg, 1);
940 930
941 if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG) 931 if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG)
942 mod_timer(&adapter->watchdog_timer, 932 mod_timer(&adapter->watchdog_timer,
943 round_jiffies(jiffies + 1)); 933 round_jiffies(jiffies + 1));
944 934
935 if (msg & IXGBE_VT_MSGTYPE_NACK)
936 pr_warn("Last Request of type %2.2x to PF Nacked\n",
937 msg & 0xFF);
938 goto out;
939 }
940
941 /*
942 * checking for the ack clears the PFACK bit. Place
943 * it back in the v2p_mailbox cache so that anyone
944 * polling for an ack will not miss it
945 */
946 if (got_ack)
947 hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
945out: 948out:
946 return IRQ_HANDLED; 949 return IRQ_HANDLED;
947} 950}