aq_ret = i40e_aq_add_macvlan(hw, vsi->seid, list, num_add, NULL);
        aq_err = hw->aq.asq_last_status;
        fcnt = i40e_update_filter_state(num_add, list, add_head, aq_ret);
-       vsi->active_filters += fcnt;
 
        if (fcnt != num_add) {
                *promisc_changed = true;
                set_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state);
-               vsi->promisc_threshold = (vsi->active_filters * 3) / 4;
                dev_warn(&vsi->back->pdev->dev,
                         "Error %s adding RX filters on %s, promiscuous mode forced on\n",
                         i40e_aq_str(hw, aq_err),
        struct i40e_hw *hw = &vsi->back->hw;
        unsigned int vlan_any_filters = 0;
        unsigned int non_vlan_filters = 0;
+       unsigned int failed_filters = 0;
        unsigned int vlan_filters = 0;
        bool promisc_changed = false;
        char vsi_name[16] = "PF";
                                /* Move the element into temporary del_list */
                                hash_del(&f->hlist);
                                hlist_add_head(&f->hlist, &tmp_del_list);
-                               vsi->active_filters--;
 
                                /* Avoid counting removed filters */
                                continue;
                                f->state = I40E_FILTER_REMOVE;
                                hash_del(&f->hlist);
                                hlist_add_head(&f->hlist, &tmp_del_list);
-                               vsi->active_filters--;
                        }
 
                        /* Also update any filters on the tmp_add list */
                add_list = NULL;
        }
 
-       /* Check to see if we can drop out of overflow promiscuous mode. */
+       /* Determine the number of active and failed filters. */
+       spin_lock_bh(&vsi->mac_filter_hash_lock);
+       vsi->active_filters = 0;
+       hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
+               if (f->state == I40E_FILTER_ACTIVE)
+                       vsi->active_filters++;
+               else if (f->state == I40E_FILTER_FAILED)
+                       failed_filters++;
+       }
+       spin_unlock_bh(&vsi->mac_filter_hash_lock);
+
+       /* If promiscuous mode has changed, we need to calculate a new
+        * threshold for when we are safe to exit
+        */
+       if (promisc_changed)
+               vsi->promisc_threshold = (vsi->active_filters * 3) / 4;
+
+       /* Check if we are able to exit overflow promiscuous mode. We can
+        * safely exit if we didn't just enter, we no longer have any failed
+        * filters, and we have reduced filters below the threshold value.
+        */
        if (test_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state) &&
+           !promisc_changed && !failed_filters &&
            (vsi->active_filters < vsi->promisc_threshold)) {
-               int failed_count = 0;
-               /* See if we have any failed filters. We can't drop out of
-                * promiscuous until these have all been deleted.
-                */
-               spin_lock_bh(&vsi->mac_filter_hash_lock);
-               hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
-                       if (f->state == I40E_FILTER_FAILED)
-                               failed_count++;
-               }
-               spin_unlock_bh(&vsi->mac_filter_hash_lock);
-               if (!failed_count) {
-                       dev_info(&pf->pdev->dev,
-                                "filter logjam cleared on %s, leaving overflow promiscuous mode\n",
-                                vsi_name);
-                       clear_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state);
-                       promisc_changed = true;
-                       vsi->promisc_threshold = 0;
-               }
+               dev_info(&pf->pdev->dev,
+                        "filter logjam cleared on %s, leaving overflow promiscuous mode\n",
+                        vsi_name);
+               clear_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state);
+               promisc_changed = true;
+               vsi->promisc_threshold = 0;
        }
 
        /* if the VF is not trusted do not do promisc */