aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc/ef10.c
diff options
context:
space:
mode:
authorEdward Cree <ecree@solarflare.com>2016-06-15 17:43:43 +0100
committerDavid S. Miller <davem@davemloft.net>2016-06-15 22:26:25 -0700
commitdd98708cf6a7981ad5bc23b1e10c548689482ef7 (patch)
treefcd520dc48e6eccc891ff98703a9fd0acb8248e6 /drivers/net/ethernet/sfc/ef10.c
parentsfc: Add efx_nic member with fixed netdev features (diff)
downloadlinux-dev-dd98708cf6a7981ad5bc23b1e10c548689482ef7.tar.xz
linux-dev-dd98708cf6a7981ad5bc23b1e10c548689482ef7.zip
sfc: Assert filter_sem write locked when required
Based on a patch by Andrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru> Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/sfc/ef10.c')
-rw-r--r--drivers/net/ethernet/sfc/ef10.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index ebe35496b294..66cc9637fd8f 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -3735,6 +3735,12 @@ static int efx_ef10_filter_table_probe(struct efx_nic *efx)
size_t outlen;
int rc;
+ if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
+ return -EINVAL;
+
+ if (efx->filter_state) /* already probed */
+ return 0;
+
table = kzalloc(sizeof(*table), GFP_KERNEL);
if (!table)
return -ENOMEM;
@@ -3846,7 +3852,6 @@ static void efx_ef10_filter_table_restore(struct efx_nic *efx)
nic_data->must_restore_filters = false;
}
-/* Caller must hold efx->filter_sem for write */
static void efx_ef10_filter_table_remove(struct efx_nic *efx)
{
struct efx_ef10_filter_table *table = efx->filter_state;
@@ -3856,6 +3861,15 @@ static void efx_ef10_filter_table_remove(struct efx_nic *efx)
int rc;
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;