mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-17 20:54:10 +00:00
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: 37d318d780
("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>
This commit is contained in:
parent
0d6835ffe5
commit
8b4b06919f
1 changed files with 20 additions and 3 deletions
|
@ -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)
|
||||||
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,
|
||||||
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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue