Commit 8b4b0691 authored by Stefan Assmann's avatar Stefan Assmann Committed by Tony Nguyen

i40e: improve locking of mac_filter_hash

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: 37d318d7 ("i40e: Remove scheduling while atomic possibility")
Fix-suggested-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarStefan Assmann <sassmann@kpanic.de>
Tested-by: default avatarKonrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 0d6835ff
...@@ -1160,12 +1160,12 @@ static int i40e_quiesce_vf_pci(struct i40e_vf *vf) ...@@ -1160,12 +1160,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 * @vsi: pointer to the vsi
* *
* called to get the number of VLANs offloaded on this VF * 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; struct i40e_mac_filter *f;
u16 num_vlans = 0, bkt; u16 num_vlans = 0, bkt;
...@@ -1178,6 +1178,23 @@ static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi) ...@@ -1178,6 +1178,23 @@ static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
return num_vlans; 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 * i40e_get_vlan_list_sync
* @vsi: pointer to the VSI * @vsi: pointer to the VSI
...@@ -1195,7 +1212,7 @@ static void i40e_get_vlan_list_sync(struct i40e_vsi *vsi, u16 *num_vlans, ...@@ -1195,7 +1212,7 @@ static void i40e_get_vlan_list_sync(struct i40e_vsi *vsi, u16 *num_vlans,
int bkt; int bkt;
spin_lock_bh(&vsi->mac_filter_hash_lock); 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); *vlan_list = kcalloc(*num_vlans, sizeof(**vlan_list), GFP_ATOMIC);
if (!(*vlan_list)) if (!(*vlan_list))
goto err; goto err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment