Commit 290d2557 authored by Jacob Keller's avatar Jacob Keller Committed by Jeff Kirsher

i40e: implement __i40e_del_filter and use where applicable

When inside a loop where we call i40e_del_filter we use an O(n^2)
pattern where i40e_del_filter calls i40e_find_filter for us. We can
avoid this O(n^2) logic by factoring a function, __i40e_del_filter() out
from the i40e_del_filter code. This allows us to re-use the delete logic
where appropriate without having to search for the filter twice.

This new function benefits several functions including i40e_vsi_add_vlan,
i40e_vsi_kill_vlan, i40e_del_mac_vlan_all, and i40e_vsi_release.

Change-ID: I75fabe0f53bf73f56b80d342e5fdcfcc28f4d3eb
Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 57b341d6
...@@ -1271,10 +1271,13 @@ struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi, ...@@ -1271,10 +1271,13 @@ struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,
} }
/** /**
* i40e_del_filter - Remove a mac/vlan filter from the VSI * __i40e_del_filter - Remove a specific filter from the VSI
* @vsi: the VSI to be searched * @vsi: VSI to remove from
* @macaddr: the MAC address * @f: the filter to remove from the list
* @vlan: the vlan *
* This function should be called instead of i40e_del_filter only if you know
* the exact filter you will remove already, such as via i40e_find_filter or
* i40e_find_mac.
* *
* NOTE: This function is expected to be called with mac_filter_list_lock * NOTE: This function is expected to be called with mac_filter_list_lock
* being held. * being held.
...@@ -1282,14 +1285,8 @@ struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi, ...@@ -1282,14 +1285,8 @@ struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,
* the "safe" variants of any list iterators, e.g. list_for_each_entry_safe() * the "safe" variants of any list iterators, e.g. list_for_each_entry_safe()
* instead of list_for_each_entry(). * instead of list_for_each_entry().
**/ **/
void i40e_del_filter(struct i40e_vsi *vsi, const u8 *macaddr, s16 vlan) static void __i40e_del_filter(struct i40e_vsi *vsi, struct i40e_mac_filter *f)
{ {
struct i40e_mac_filter *f;
if (!vsi || !macaddr)
return;
f = i40e_find_filter(vsi, macaddr, vlan);
if (!f) if (!f)
return; return;
...@@ -1307,6 +1304,29 @@ void i40e_del_filter(struct i40e_vsi *vsi, const u8 *macaddr, s16 vlan) ...@@ -1307,6 +1304,29 @@ void i40e_del_filter(struct i40e_vsi *vsi, const u8 *macaddr, s16 vlan)
} }
} }
/**
* i40e_del_filter - Remove a MAC/VLAN filter from the VSI
* @vsi: the VSI to be searched
* @macaddr: the MAC address
* @vlan: the VLAN
*
* NOTE: This function is expected to be called with mac_filter_list_lock
* being held.
* ANOTHER NOTE: This function MUST be called from within the context of
* the "safe" variants of any list iterators, e.g. list_for_each_entry_safe()
* instead of list_for_each_entry().
**/
void i40e_del_filter(struct i40e_vsi *vsi, const u8 *macaddr, s16 vlan)
{
struct i40e_mac_filter *f;
if (!vsi || !macaddr)
return;
f = i40e_find_filter(vsi, macaddr, vlan);
__i40e_del_filter(vsi, f);
}
/** /**
* i40e_put_mac_in_vlan - Make macvlan filters from macaddrs and vlans * i40e_put_mac_in_vlan - Make macvlan filters from macaddrs and vlans
* @vsi: the VSI to be searched * @vsi: the VSI to be searched
...@@ -1349,21 +1369,22 @@ struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi, ...@@ -1349,21 +1369,22 @@ struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi,
**/ **/
int i40e_del_mac_all_vlan(struct i40e_vsi *vsi, const u8 *macaddr) int i40e_del_mac_all_vlan(struct i40e_vsi *vsi, const u8 *macaddr)
{ {
struct i40e_mac_filter *f = NULL; struct i40e_mac_filter *f, *ftmp;
int changed = 0; bool found = false;
WARN(!spin_is_locked(&vsi->mac_filter_list_lock), WARN(!spin_is_locked(&vsi->mac_filter_list_lock),
"Missing mac_filter_list_lock\n"); "Missing mac_filter_list_lock\n");
list_for_each_entry(f, &vsi->mac_filter_list, list) { list_for_each_entry_safe(f, ftmp, &vsi->mac_filter_list, list) {
if (ether_addr_equal(macaddr, f->macaddr)) if (ether_addr_equal(macaddr, f->macaddr)) {
f->state = I40E_FILTER_REMOVE; __i40e_del_filter(vsi, f);
found = true;
}
} }
if (changed) {
vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED; if (found)
vsi->back->flags |= I40E_FLAG_FILTER_SYNC;
return 0; return 0;
} else
return -ENOENT; return -ENOENT;
} }
/** /**
...@@ -2256,7 +2277,7 @@ static void i40e_vlan_rx_register(struct net_device *netdev, u32 features) ...@@ -2256,7 +2277,7 @@ static void i40e_vlan_rx_register(struct net_device *netdev, u32 features)
**/ **/
int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid) int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid)
{ {
struct i40e_mac_filter *f, *ftmp, *add_f; struct i40e_mac_filter *f, *ftmp, *add_f, *del_f;
/* Locked once because all functions invoked below iterates list*/ /* Locked once because all functions invoked below iterates list*/
spin_lock_bh(&vsi->mac_filter_list_lock); spin_lock_bh(&vsi->mac_filter_list_lock);
...@@ -2290,11 +2311,11 @@ int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid) ...@@ -2290,11 +2311,11 @@ int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid)
* with 0, so we now accept untagged and specified tagged traffic * with 0, so we now accept untagged and specified tagged traffic
* (and not all tags along with untagged) * (and not all tags along with untagged)
*/ */
if (vid > 0) { if (vid > 0 && vsi->netdev) {
if (vsi->netdev && i40e_find_filter(vsi, vsi->netdev->dev_addr, del_f = i40e_find_filter(vsi, vsi->netdev->dev_addr,
I40E_VLAN_ANY)) { I40E_VLAN_ANY);
i40e_del_filter(vsi, vsi->netdev->dev_addr, if (del_f) {
I40E_VLAN_ANY); __i40e_del_filter(vsi, del_f);
add_f = i40e_add_filter(vsi, vsi->netdev->dev_addr, 0); add_f = i40e_add_filter(vsi, vsi->netdev->dev_addr, 0);
if (!add_f) { if (!add_f) {
dev_info(&vsi->back->pdev->dev, dev_info(&vsi->back->pdev->dev,
...@@ -2311,9 +2332,11 @@ int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid) ...@@ -2311,9 +2332,11 @@ int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid)
list_for_each_entry_safe(f, ftmp, &vsi->mac_filter_list, list) { list_for_each_entry_safe(f, ftmp, &vsi->mac_filter_list, list) {
if (f->state == I40E_FILTER_REMOVE) if (f->state == I40E_FILTER_REMOVE)
continue; continue;
if (!i40e_find_filter(vsi, f->macaddr, I40E_VLAN_ANY)) del_f = i40e_find_filter(vsi, f->macaddr,
I40E_VLAN_ANY);
if (!del_f)
continue; continue;
i40e_del_filter(vsi, f->macaddr, I40E_VLAN_ANY); __i40e_del_filter(vsi, del_f);
add_f = i40e_add_filter(vsi, f->macaddr, 0); add_f = i40e_add_filter(vsi, f->macaddr, 0);
if (!add_f) { if (!add_f) {
dev_info(&vsi->back->pdev->dev, dev_info(&vsi->back->pdev->dev,
...@@ -2353,8 +2376,10 @@ int i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid) ...@@ -2353,8 +2376,10 @@ int i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid)
if (vsi->netdev) if (vsi->netdev)
i40e_del_filter(vsi, netdev->dev_addr, vid); i40e_del_filter(vsi, netdev->dev_addr, vid);
list_for_each_entry_safe(f, ftmp, &vsi->mac_filter_list, list) list_for_each_entry_safe(f, ftmp, &vsi->mac_filter_list, list) {
i40e_del_filter(vsi, f->macaddr, vid); if (f->vlan == vid)
__i40e_del_filter(vsi, f);
}
/* go through all the filters for this VSI and if there is only /* go through all the filters for this VSI and if there is only
* vid == 0 it means there are no other filters, so vid 0 must * vid == 0 it means there are no other filters, so vid 0 must
...@@ -2386,7 +2411,8 @@ int i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid) ...@@ -2386,7 +2411,8 @@ int i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid)
if (!filter_count) { if (!filter_count) {
list_for_each_entry_safe(f, ftmp, &vsi->mac_filter_list, list) { list_for_each_entry_safe(f, ftmp, &vsi->mac_filter_list, list) {
i40e_del_filter(vsi, f->macaddr, 0); if (!f->vlan)
__i40e_del_filter(vsi, f);
add_f = i40e_add_filter(vsi, f->macaddr, I40E_VLAN_ANY); add_f = i40e_add_filter(vsi, f->macaddr, I40E_VLAN_ANY);
if (!add_f) { if (!add_f) {
dev_info(&vsi->back->pdev->dev, dev_info(&vsi->back->pdev->dev,
...@@ -9455,7 +9481,7 @@ int i40e_vsi_release(struct i40e_vsi *vsi) ...@@ -9455,7 +9481,7 @@ int i40e_vsi_release(struct i40e_vsi *vsi)
/* make sure any remaining filters are marked for deletion */ /* make sure any remaining filters are marked for deletion */
list_for_each_entry_safe(f, ftmp, &vsi->mac_filter_list, list) list_for_each_entry_safe(f, ftmp, &vsi->mac_filter_list, list)
i40e_del_filter(vsi, f->macaddr, f->vlan); __i40e_del_filter(vsi, f);
spin_unlock_bh(&vsi->mac_filter_list_lock); spin_unlock_bh(&vsi->mac_filter_list_lock);
......
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