Skip to content

Commit

Permalink
ixgbe: Fix race when the VF driver does a reset
Browse files Browse the repository at this point in the history
[ Upstream commit 96d1a731611f711f0cb82cea93363ae2ea8cb028 ]

When the VF driver does a reset, it (at least the Linux one) writes to
the VFCTRL register to issue a reset and then immediately sends a reset
message using the mailbox API. This is racy because when the PF driver
detects that the VFCTRL register reset pin has been asserted, it clears
the mailbox memory. Depending on ordering, the reset message sent by
the VF could be cleared by the PF driver. It then responds to the
cleared message with a NACK which causes the VF driver to malfunction.
Fix this by deferring clearing the mailbox memory until the reset
message is received.

Fixes: 939b701 ("ixgbe: fix driver behaviour after issuing VFLR")
Signed-off-by: Ross Lagerwall <[email protected]>
Tested-by: Andrew Bowers <[email protected]>
Signed-off-by: Jeff Kirsher <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
rosslagerwall authored and gregkh committed Jan 13, 2019
1 parent 3bfed54 commit 27f59f3
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,6 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
u8 num_tcs = adapter->hw_tcs;
u32 reg_val;
u32 queue;
u32 word;

/* remove VLAN filters beloning to this VF */
ixgbe_clear_vf_vlans(adapter, vf);
Expand Down Expand Up @@ -754,6 +753,14 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
}
}

IXGBE_WRITE_FLUSH(hw);
}

static void ixgbe_vf_clear_mbx(struct ixgbe_adapter *adapter, u32 vf)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 word;

/* Clear VF's mailbox memory */
for (word = 0; word < IXGBE_VFMAILBOX_SIZE; word++)
IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf), word, 0);
Expand Down Expand Up @@ -827,6 +834,8 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
/* reset the filters for the device */
ixgbe_vf_reset_event(adapter, vf);

ixgbe_vf_clear_mbx(adapter, vf);

/* set vf mac address */
if (!is_zero_ether_addr(vf_mac))
ixgbe_set_vf_mac(adapter, vf, vf_mac);
Expand Down

0 comments on commit 27f59f3

Please sign in to comment.