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>
This commit is contained in:
Greg Rose 2012-01-18 22:13:31 +00:00 committed by David S. Miller
parent 795be954dc
commit 375b27cf5d
1 changed files with 21 additions and 18 deletions

View File

@ -917,31 +917,34 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
struct ixgbe_hw *hw = &adapter->hw;
u32 eicr;
u32 msg;
bool got_ack = false;
eicr = IXGBE_READ_REG(hw, IXGBE_VTEICS);
IXGBE_WRITE_REG(hw, IXGBE_VTEICR, eicr);
if (!hw->mbx.ops.check_for_ack(hw)) {
/*
* checking for the ack clears the PFACK bit. Place
* it back in the v2p_mailbox cache so that anyone
* polling for an ack will not miss it. Also
* avoid the read below because the code to read
* the mailbox will also clear the ack bit. This was
* causing lost acks. Just cache the bit and exit
* the IRQ handler.
*/
hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
if (!hw->mbx.ops.check_for_ack(hw))
got_ack = true;
if (!hw->mbx.ops.check_for_msg(hw)) {
hw->mbx.ops.read(hw, &msg, 1);
if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG)
mod_timer(&adapter->watchdog_timer,
round_jiffies(jiffies + 1));
if (msg & IXGBE_VT_MSGTYPE_NACK)
pr_warn("Last Request of type %2.2x to PF Nacked\n",
msg & 0xFF);
goto out;
}
/* Not an ack interrupt, go ahead and read the message */
hw->mbx.ops.read(hw, &msg, 1);
if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG)
mod_timer(&adapter->watchdog_timer,
round_jiffies(jiffies + 1));
/*
* checking for the ack clears the PFACK bit. Place
* it back in the v2p_mailbox cache so that anyone
* polling for an ack will not miss it
*/
if (got_ack)
hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
out:
return IRQ_HANDLED;
}