sfc: factor out efx_mcdi_filter_table_down() from _remove()
authorEdward Cree <ecree@solarflare.com>
Thu, 2 Jul 2020 16:30:39 +0000 (17:30 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 2 Jul 2020 21:47:40 +0000 (14:47 -0700)
_down() merely removes all our filters and VLANs, it doesn't free
 efx->filter_state itself.

Signed-off-by: Edward Cree <ecree@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/mcdi_filters.c
drivers/net/ethernet/sfc/mcdi_filters.h

index 74ee06f..283f682 100644 (file)
@@ -1459,7 +1459,7 @@ not_restored:
                table->must_restore_filters = false;
 }
 
-void efx_mcdi_filter_table_remove(struct efx_nic *efx)
+void efx_mcdi_filter_table_down(struct efx_nic *efx)
 {
        struct efx_mcdi_filter_table *table = efx->filter_state;
        MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
@@ -1467,21 +1467,11 @@ void efx_mcdi_filter_table_remove(struct efx_nic *efx)
        unsigned int filter_idx;
        int rc;
 
-       efx_mcdi_filter_cleanup_vlans(efx);
-       efx->filter_state = NULL;
-       /*
-        * If we were called without locking, then it's not safe to free
-        * the table as others might be using it.  So we just WARN, leak
-        * the memory, and potentially get an inconsistent filter table
-        * state.
-        * This should never actually happen.
-        */
-       if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
-               return;
-
        if (!table)
                return;
 
+       efx_mcdi_filter_cleanup_vlans(efx);
+
        for (filter_idx = 0; filter_idx < EFX_MCDI_FILTER_TBL_ROWS; filter_idx++) {
                spec = efx_mcdi_filter_entry_spec(table, filter_idx);
                if (!spec)
@@ -1501,6 +1491,27 @@ void efx_mcdi_filter_table_remove(struct efx_nic *efx)
                                   __func__, filter_idx);
                kfree(spec);
        }
+}
+
+void efx_mcdi_filter_table_remove(struct efx_nic *efx)
+{
+       struct efx_mcdi_filter_table *table = efx->filter_state;
+
+       efx_mcdi_filter_table_down(efx);
+
+       efx->filter_state = NULL;
+       /*
+        * If we were called without locking, then it's not safe to free
+        * the table as others might be using it.  So we just WARN, leak
+        * the memory, and potentially get an inconsistent filter table
+        * state.
+        * This should never actually happen.
+        */
+       if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
+               return;
+
+       if (!table)
+               return;
 
        vfree(table->entry);
        kfree(table);
index 03a8bf7..23f9d08 100644 (file)
@@ -93,6 +93,7 @@ struct efx_mcdi_filter_table {
 };
 
 int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining);
+void efx_mcdi_filter_table_down(struct efx_nic *efx);
 void efx_mcdi_filter_table_remove(struct efx_nic *efx);
 void efx_mcdi_filter_table_restore(struct efx_nic *efx);