i40e: acquire VSI pointer only after VF is initialized

[ Upstream commit 67a3c6b3cc ]

This change simplifies the VF initialization check and also minimizes
the delay between acquiring the VSI pointer and using it. As known by
the commit being fixed, there is a risk of the VSI pointer getting
changed. Therefore minimize the delay between getting and using the
pointer.

Fixes: 9889707b06 ("i40e: Fix crash caused by stress setting of VF MAC addresses")
Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Stefan Assmann
2020-11-30 14:12:57 +01:00
committed by Greg Kroah-Hartman
parent b2a76ea047
commit d11a1402ec

View File

@@ -4046,20 +4046,16 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
goto error_param;
vf = &pf->vf[vf_id];
vsi = pf->vsi[vf->lan_vsi_idx];
/* When the VF is resetting wait until it is done.
* It can take up to 200 milliseconds,
* but wait for up to 300 milliseconds to be safe.
* If the VF is indeed in reset, the vsi pointer has
* to show on the newly loaded vsi under pf->vsi[id].
* Acquire the VSI pointer only after the VF has been
* properly initialized.
*/
for (i = 0; i < 15; i++) {
if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {
if (i > 0)
vsi = pf->vsi[vf->lan_vsi_idx];
if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states))
break;
}
msleep(20);
}
if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {
@@ -4068,6 +4064,7 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
ret = -EAGAIN;
goto error_param;
}
vsi = pf->vsi[vf->lan_vsi_idx];
if (is_multicast_ether_addr(mac)) {
dev_err(&pf->pdev->dev,