Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd98708c authored by Edward Cree's avatar Edward Cree Committed by David S. Miller
Browse files

sfc: Assert filter_sem write locked when required



Based on a patch by Andrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru>

Signed-off-by: default avatarEdward Cree <ecree@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ebfcd0fd
Loading
Loading
Loading
Loading
+15 −1
Original line number Original line Diff line number Diff line
@@ -3735,6 +3735,12 @@ static int efx_ef10_filter_table_probe(struct efx_nic *efx)
	size_t outlen;
	size_t outlen;
	int rc;
	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);
	table = kzalloc(sizeof(*table), GFP_KERNEL);
	if (!table)
	if (!table)
		return -ENOMEM;
		return -ENOMEM;
@@ -3846,7 +3852,6 @@ static void efx_ef10_filter_table_restore(struct efx_nic *efx)
		nic_data->must_restore_filters = false;
		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)
static void efx_ef10_filter_table_remove(struct efx_nic *efx)
{
{
	struct efx_ef10_filter_table *table = efx->filter_state;
	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;
	int rc;


	efx->filter_state = NULL;
	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)
	if (!table)
		return;
		return;


+9 −0
Original line number Original line Diff line number Diff line
@@ -274,4 +274,13 @@ static inline void efx_device_detach_sync(struct efx_nic *efx)
	netif_tx_unlock_bh(dev);
	netif_tx_unlock_bh(dev);
}
}


static inline bool efx_rwsem_assert_write_locked(struct rw_semaphore *sem)
{
	if (WARN_ON(down_read_trylock(sem))) {
		up_read(sem);
		return false;
	}
	return true;
}

#endif /* EFX_EFX_H */
#endif /* EFX_EFX_H */