Commit 4a2ce27b authored by Jacob Keller's avatar Jacob Keller Committed by Jeff Kirsher

i40e: properly cleanup on allocation failure in i40e_sync_vsi_filters

Currently, we fail to correctly restore filters on the temporary add
list when we fail to allocate memory either for deletion or addition.
Replace calls to "goto out;" with calls to a new location that correctly
handles memory allocation failures.

Note that it is safe for us to call i40e_undo_filter_entries on the
tmp_del_list even after we've deleted filters because at this point it
will be empty, so we don't need to separate the logic for add and
delete failure.

Change-Id: Iee107fd219c6e03e2fd9645c2debf8e8384a8521
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 278e7d0b
...@@ -1683,15 +1683,16 @@ static void i40e_set_rx_mode(struct net_device *netdev) ...@@ -1683,15 +1683,16 @@ static void i40e_set_rx_mode(struct net_device *netdev)
} }
/** /**
* i40e_undo_del_filter_entries - Undo the changes made to MAC filter entries * i40e_undo_filter_entries - Undo the changes made to MAC filter entries
* @vsi: pointer to vsi struct * @vsi: Pointer to VSI struct
* @from: Pointer to list which contains MAC filter entries - changes to * @from: Pointer to list which contains MAC filter entries - changes to
* those entries needs to be undone. * those entries needs to be undone.
* *
* MAC filter entries from list were slated to be removed from device. * MAC filter entries from list were slated to be sent to firmware, either for
* addition or deletion.
**/ **/
static void i40e_undo_del_filter_entries(struct i40e_vsi *vsi, static void i40e_undo_filter_entries(struct i40e_vsi *vsi,
struct hlist_head *from) struct hlist_head *from)
{ {
struct i40e_mac_filter *f; struct i40e_mac_filter *f;
struct hlist_node *h; struct hlist_node *h;
...@@ -1840,14 +1841,8 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -1840,14 +1841,8 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
list_size = filter_list_len * list_size = filter_list_len *
sizeof(struct i40e_aqc_remove_macvlan_element_data); sizeof(struct i40e_aqc_remove_macvlan_element_data);
del_list = kzalloc(list_size, GFP_ATOMIC); del_list = kzalloc(list_size, GFP_ATOMIC);
if (!del_list) { if (!del_list)
/* Undo VSI's MAC filter entry element updates */ goto err_no_memory;
spin_lock_bh(&vsi->mac_filter_hash_lock);
i40e_undo_del_filter_entries(vsi, &tmp_del_list);
spin_unlock_bh(&vsi->mac_filter_hash_lock);
retval = -ENOMEM;
goto out;
}
hlist_for_each_entry_safe(f, h, &tmp_del_list, hlist) { hlist_for_each_entry_safe(f, h, &tmp_del_list, hlist) {
cmd_flags = 0; cmd_flags = 0;
...@@ -1924,10 +1919,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -1924,10 +1919,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
list_size = filter_list_len * list_size = filter_list_len *
sizeof(struct i40e_aqc_add_macvlan_element_data); sizeof(struct i40e_aqc_add_macvlan_element_data);
add_list = kzalloc(list_size, GFP_ATOMIC); add_list = kzalloc(list_size, GFP_ATOMIC);
if (!add_list) { if (!add_list)
retval = -ENOMEM; goto err_no_memory;
goto out;
}
num_add = 0; num_add = 0;
hlist_for_each_entry(f, &tmp_add_list, hlist) { hlist_for_each_entry(f, &tmp_add_list, hlist) {
if (test_bit(__I40E_FILTER_OVERFLOW_PROMISC, if (test_bit(__I40E_FILTER_OVERFLOW_PROMISC,
...@@ -2152,6 +2146,17 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -2152,6 +2146,17 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
clear_bit(__I40E_CONFIG_BUSY, &vsi->state); clear_bit(__I40E_CONFIG_BUSY, &vsi->state);
return retval; return retval;
err_no_memory:
/* Restore elements on the temporary add and delete lists */
spin_lock_bh(&vsi->mac_filter_hash_lock);
i40e_undo_filter_entries(vsi, &tmp_del_list);
i40e_undo_filter_entries(vsi, &tmp_add_list);
spin_unlock_bh(&vsi->mac_filter_hash_lock);
vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
clear_bit(__I40E_CONFIG_BUSY, &vsi->state);
return -ENOMEM;
} }
/** /**
......
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