* @adapter: board private structure
  * @vlan: vlan tag
  *
- * Returns ptr to the filter object or NULL
+ * Returns ptr to the filter object or NULL. Must be called while holding the
+ * mac_vlan_list_lock.
  **/
 static struct
 i40evf_vlan_filter *i40evf_find_vlan(struct i40evf_adapter *adapter, u16 vlan)
 i40evf_vlan_filter *i40evf_add_vlan(struct i40evf_adapter *adapter, u16 vlan)
 {
        struct i40evf_vlan_filter *f = NULL;
-       int count = 50;
 
-       while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
-                               &adapter->crit_section)) {
-               udelay(1);
-               if (--count == 0)
-                       goto out;
-       }
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
 
        f = i40evf_find_vlan(adapter, vlan);
        if (!f) {
        }
 
 clearout:
-       clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
-out:
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
        return f;
 }
 
 static void i40evf_del_vlan(struct i40evf_adapter *adapter, u16 vlan)
 {
        struct i40evf_vlan_filter *f;
-       int count = 50;
 
-       while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
-                               &adapter->crit_section)) {
-               udelay(1);
-               if (--count == 0)
-                       return;
-       }
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
 
        f = i40evf_find_vlan(adapter, vlan);
        if (f) {
                f->remove = true;
                adapter->aq_required |= I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
        }
-       clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
+
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
 }
 
 /**
  * @adapter: board private structure
  * @macaddr: the MAC address
  *
- * Returns ptr to the filter object or NULL
+ * Returns ptr to the filter object or NULL. Must be called while holding the
+ * mac_vlan_list_lock.
  **/
 static struct
 i40evf_mac_filter *i40evf_find_filter(struct i40evf_adapter *adapter,
                                     u8 *macaddr)
 {
        struct i40evf_mac_filter *f;
-       int count = 50;
 
        if (!macaddr)
                return NULL;
 
-       while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
-                               &adapter->crit_section)) {
-               udelay(1);
-               if (--count == 0)
-                       return NULL;
-       }
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
 
        f = i40evf_find_filter(adapter, macaddr);
        if (!f) {
                f = kzalloc(sizeof(*f), GFP_ATOMIC);
-               if (!f) {
-                       clear_bit(__I40EVF_IN_CRITICAL_TASK,
-                                 &adapter->crit_section);
-                       return NULL;
-               }
+               if (!f)
+                       goto clearout;
 
                ether_addr_copy(f->macaddr, macaddr);
 
                f->remove = false;
        }
 
-       clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
+clearout:
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
        return f;
 }
 
        if (adapter->flags & I40EVF_FLAG_ADDR_SET_BY_PF)
                return -EPERM;
 
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+
        f = i40evf_find_filter(adapter, hw->mac.addr);
        if (f) {
                f->remove = true;
                adapter->aq_required |= I40EVF_FLAG_AQ_DEL_MAC_FILTER;
        }
 
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
+
        f = i40evf_add_filter(adapter, addr->sa_data);
        if (f) {
                ether_addr_copy(hw->mac.addr, addr->sa_data);
        struct netdev_hw_addr *uca;
        struct netdev_hw_addr *mca;
        struct netdev_hw_addr *ha;
-       int count = 50;
 
        /* add addr if not already in the filter list */
        netdev_for_each_uc_addr(uca, netdev) {
                i40evf_add_filter(adapter, mca->addr);
        }
 
-       while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
-                               &adapter->crit_section)) {
-               udelay(1);
-               if (--count == 0) {
-                       dev_err(&adapter->pdev->dev,
-                               "Failed to get lock in %s\n", __func__);
-                       return;
-               }
-       }
-       /* remove filter if not in netdev list */
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+
        list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
                netdev_for_each_mc_addr(mca, netdev)
                        if (ether_addr_equal(mca->addr, f->macaddr))
                 adapter->flags & I40EVF_FLAG_ALLMULTI_ON)
                adapter->aq_required |= I40EVF_FLAG_AQ_RELEASE_ALLMULTI;
 
-       clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
 }
 
 /**
        i40evf_napi_disable_all(adapter);
        i40evf_irq_disable(adapter);
 
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+
        /* remove all MAC filters */
        list_for_each_entry(f, &adapter->mac_filter_list, list) {
                f->remove = true;
        list_for_each_entry(f, &adapter->vlan_filter_list, list) {
                f->remove = true;
        }
+
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
+
        if (!(adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) &&
            adapter->state != __I40EVF_RESETTING) {
                /* cancel any current operation */
                i40evf_free_all_rx_resources(adapter);
        }
 
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+
        /* Delete all of the filters, both MAC and VLAN. */
        list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
                list_del(&f->list);
                kfree(fv);
        }
 
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
+
        i40evf_free_misc_irq(adapter);
        i40evf_reset_interrupt_capability(adapter);
        i40evf_free_queues(adapter);
        adapter->aq_required |= I40EVF_FLAG_AQ_GET_CONFIG;
        adapter->aq_required |= I40EVF_FLAG_AQ_MAP_VECTORS;
 
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+
        /* re-add all MAC filters */
        list_for_each_entry(f, &adapter->mac_filter_list, list) {
                f->add = true;
        list_for_each_entry(vlf, &adapter->vlan_filter_list, list) {
                vlf->add = true;
        }
+
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
+
        adapter->aq_required |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
        adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
        clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
        mutex_init(&hw->aq.asq_mutex);
        mutex_init(&hw->aq.arq_mutex);
 
+       spin_lock_init(&adapter->mac_vlan_list_lock);
+
        INIT_LIST_HEAD(&adapter->mac_filter_list);
        INIT_LIST_HEAD(&adapter->vlan_filter_list);
 
        i40evf_free_all_rx_resources(adapter);
        i40evf_free_queues(adapter);
        kfree(adapter->vf_res);
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
        /* If we got removed before an up/down sequence, we've got a filter
         * hanging out there that we need to get rid of.
         */
                kfree(f);
        }
 
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
+
        free_netdev(netdev);
 
        pci_disable_pcie_error_reporting(pdev);
 
                        adapter->current_op);
                return;
        }
+
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+
        list_for_each_entry(f, &adapter->mac_filter_list, list) {
                if (f->add)
                        count++;
        }
        if (!count) {
                adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER;
+               spin_unlock_bh(&adapter->mac_vlan_list_lock);
                return;
        }
        adapter->current_op = VIRTCHNL_OP_ADD_ETH_ADDR;
        }
 
        veal = kzalloc(len, GFP_KERNEL);
-       if (!veal)
+       if (!veal) {
+               spin_unlock_bh(&adapter->mac_vlan_list_lock);
                return;
+       }
 
        veal->vsi_id = adapter->vsi_res->vsi_id;
        veal->num_elements = count;
        }
        if (!more)
                adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER;
+
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
+
        i40evf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_ETH_ADDR,
                           (u8 *)veal, len);
        kfree(veal);
                        adapter->current_op);
                return;
        }
+
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+
        list_for_each_entry(f, &adapter->mac_filter_list, list) {
                if (f->remove)
                        count++;
        }
        if (!count) {
                adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER;
+               spin_unlock_bh(&adapter->mac_vlan_list_lock);
                return;
        }
        adapter->current_op = VIRTCHNL_OP_DEL_ETH_ADDR;
                more = true;
        }
        veal = kzalloc(len, GFP_KERNEL);
-       if (!veal)
+       if (!veal) {
+               spin_unlock_bh(&adapter->mac_vlan_list_lock);
                return;
+       }
 
        veal->vsi_id = adapter->vsi_res->vsi_id;
        veal->num_elements = count;
        }
        if (!more)
                adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER;
+
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
+
        i40evf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_ETH_ADDR,
                           (u8 *)veal, len);
        kfree(veal);
                return;
        }
 
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+
        list_for_each_entry(f, &adapter->vlan_filter_list, list) {
                if (f->add)
                        count++;
        }
        if (!count) {
                adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
+               spin_unlock_bh(&adapter->mac_vlan_list_lock);
                return;
        }
        adapter->current_op = VIRTCHNL_OP_ADD_VLAN;
                more = true;
        }
        vvfl = kzalloc(len, GFP_KERNEL);
-       if (!vvfl)
+       if (!vvfl) {
+               spin_unlock_bh(&adapter->mac_vlan_list_lock);
                return;
+       }
 
        vvfl->vsi_id = adapter->vsi_res->vsi_id;
        vvfl->num_elements = count;
        }
        if (!more)
                adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
+
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
+
        i40evf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
        kfree(vvfl);
 }
                return;
        }
 
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+
        list_for_each_entry(f, &adapter->vlan_filter_list, list) {
                if (f->remove)
                        count++;
        }
        if (!count) {
                adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
+               spin_unlock_bh(&adapter->mac_vlan_list_lock);
                return;
        }
        adapter->current_op = VIRTCHNL_OP_DEL_VLAN;
                more = true;
        }
        vvfl = kzalloc(len, GFP_KERNEL);
-       if (!vvfl)
+       if (!vvfl) {
+               spin_unlock_bh(&adapter->mac_vlan_list_lock);
                return;
+       }
 
        vvfl->vsi_id = adapter->vsi_res->vsi_id;
        vvfl->num_elements = count;
        }
        if (!more)
                adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
+
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
+
        i40evf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len);
        kfree(vvfl);
 }