Skip to content

Commit

Permalink
i40e: improve locking of mac_filter_hash
Browse files Browse the repository at this point in the history
[ Upstream commit 8b4b069 ]

i40e_config_vf_promiscuous_mode() calls
i40e_getnum_vf_vsi_vlan_filters() without acquiring the
mac_filter_hash_lock spinlock.

This is unsafe because mac_filter_hash may get altered in another thread
while i40e_getnum_vf_vsi_vlan_filters() traverses the hashes.

Simply adding the spinlock in i40e_getnum_vf_vsi_vlan_filters() is not
possible as it already gets called in i40e_get_vlan_list_sync() with the
spinlock held. Therefore adding a wrapper that acquires the spinlock and
call the correct function where appropriate.

Fixes: 37d318d ("i40e: Remove scheduling while atomic possibility")
Fix-suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
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>
  • Loading branch information
sassmann authored and gregkh committed Sep 15, 2021
1 parent 5ac21a4 commit f32b433
Showing 1 changed file with 20 additions and 3 deletions.
23 changes: 20 additions & 3 deletions drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
Expand Up @@ -1107,12 +1107,12 @@ static int i40e_quiesce_vf_pci(struct i40e_vf *vf)
}

/**
* i40e_getnum_vf_vsi_vlan_filters
* __i40e_getnum_vf_vsi_vlan_filters
* @vsi: pointer to the vsi
*
* called to get the number of VLANs offloaded on this VF
**/
static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
static int __i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
{
struct i40e_mac_filter *f;
u16 num_vlans = 0, bkt;
Expand All @@ -1125,6 +1125,23 @@ static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
return num_vlans;
}

/**
* i40e_getnum_vf_vsi_vlan_filters
* @vsi: pointer to the vsi
*
* wrapper for __i40e_getnum_vf_vsi_vlan_filters() with spinlock held
**/
static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
{
int num_vlans;

spin_lock_bh(&vsi->mac_filter_hash_lock);
num_vlans = __i40e_getnum_vf_vsi_vlan_filters(vsi);
spin_unlock_bh(&vsi->mac_filter_hash_lock);

return num_vlans;
}

/**
* i40e_get_vlan_list_sync
* @vsi: pointer to the VSI
Expand All @@ -1142,7 +1159,7 @@ static void i40e_get_vlan_list_sync(struct i40e_vsi *vsi, u16 *num_vlans,
int bkt;

spin_lock_bh(&vsi->mac_filter_hash_lock);
*num_vlans = i40e_getnum_vf_vsi_vlan_filters(vsi);
*num_vlans = __i40e_getnum_vf_vsi_vlan_filters(vsi);
*vlan_list = kcalloc(*num_vlans, sizeof(**vlan_list), GFP_ATOMIC);
if (!(*vlan_list))
goto err;
Expand Down

0 comments on commit f32b433

Please sign in to comment.