diff options
author | Greg Rose <gregory.v.rose@intel.com> | 2012-01-18 17:13:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-01-19 12:35:06 -0500 |
commit | 375b27cf5db963e2bc2a34dc5643d0d7ceca1ee2 (patch) | |
tree | 5448047154a5c4676685f8665d8af6b96647d68b | |
parent | 795be954dcc4a72329c8591aafe5eadb03b264af (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.c | 39 |
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; | ||
945 | out: | 948 | out: |
946 | return IRQ_HANDLED; | 949 | return IRQ_HANDLED; |
947 | } | 950 | } |