From 965470ee76988af234e23d559f5915747fe1b073 Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Thu, 2 Jul 2020 17:30:39 +0100 Subject: [PATCH] sfc: factor out efx_mcdi_filter_table_down() from _remove() _down() merely removes all our filters and VLANs, it doesn't free efx->filter_state itself. Signed-off-by: Edward Cree Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/mcdi_filters.c | 37 +++++++++++++++++++++------------ drivers/net/ethernet/sfc/mcdi_filters.h | 1 + 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/sfc/mcdi_filters.c b/drivers/net/ethernet/sfc/mcdi_filters.c index 74ee06f..283f682 100644 --- a/drivers/net/ethernet/sfc/mcdi_filters.c +++ b/drivers/net/ethernet/sfc/mcdi_filters.c @@ -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); diff --git a/drivers/net/ethernet/sfc/mcdi_filters.h b/drivers/net/ethernet/sfc/mcdi_filters.h index 03a8bf7..23f9d08 100644 --- a/drivers/net/ethernet/sfc/mcdi_filters.h +++ b/drivers/net/ethernet/sfc/mcdi_filters.h @@ -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); -- 2.7.4