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

Commit 1ff9c66b authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'sfc-filter-locking-fixes'



Bert Kenward says:

====================
sfc: filter locking fixes

Two fixes for sfc ef10 filter table locking. Initially spotted
by lockdep, but one issue has also been seen in normal use.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9e3bff92 193f2003
Loading
Loading
Loading
Loading
+21 −9
Original line number Diff line number Diff line
@@ -4288,7 +4288,7 @@ static int efx_ef10_filter_pri(struct efx_ef10_filter_table *table,
	return -EPROTONOSUPPORT;
}

static s32 efx_ef10_filter_insert(struct efx_nic *efx,
static s32 efx_ef10_filter_insert_locked(struct efx_nic *efx,
					 struct efx_filter_spec *spec,
					 bool replace_equal)
{
@@ -4307,7 +4307,7 @@ static s32 efx_ef10_filter_insert(struct efx_nic *efx,
	bool is_mc_recip;
	s32 rc;

	down_read(&efx->filter_sem);
	WARN_ON(!rwsem_is_locked(&efx->filter_sem));
	table = efx->filter_state;
	down_write(&table->lock);

@@ -4498,10 +4498,22 @@ static s32 efx_ef10_filter_insert(struct efx_nic *efx,
	if (rss_locked)
		mutex_unlock(&efx->rss_lock);
	up_write(&table->lock);
	up_read(&efx->filter_sem);
	return rc;
}

static s32 efx_ef10_filter_insert(struct efx_nic *efx,
				  struct efx_filter_spec *spec,
				  bool replace_equal)
{
	s32 ret;

	down_read(&efx->filter_sem);
	ret = efx_ef10_filter_insert_locked(efx, spec, replace_equal);
	up_read(&efx->filter_sem);

	return ret;
}

static void efx_ef10_filter_update_rx_scatter(struct efx_nic *efx)
{
	/* no need to do anything here on EF10 */
@@ -5285,7 +5297,7 @@ static int efx_ef10_filter_insert_addr_list(struct efx_nic *efx,
		EFX_WARN_ON_PARANOID(ids[i] != EFX_EF10_FILTER_ID_INVALID);
		efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
		efx_filter_set_eth_local(&spec, vlan->vid, addr_list[i].addr);
		rc = efx_ef10_filter_insert(efx, &spec, true);
		rc = efx_ef10_filter_insert_locked(efx, &spec, true);
		if (rc < 0) {
			if (rollback) {
				netif_info(efx, drv, efx->net_dev,
@@ -5314,7 +5326,7 @@ static int efx_ef10_filter_insert_addr_list(struct efx_nic *efx,
		efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
		eth_broadcast_addr(baddr);
		efx_filter_set_eth_local(&spec, vlan->vid, baddr);
		rc = efx_ef10_filter_insert(efx, &spec, true);
		rc = efx_ef10_filter_insert_locked(efx, &spec, true);
		if (rc < 0) {
			netif_warn(efx, drv, efx->net_dev,
				   "Broadcast filter insert failed rc=%d\n", rc);
@@ -5370,7 +5382,7 @@ static int efx_ef10_filter_insert_def(struct efx_nic *efx,
	if (vlan->vid != EFX_FILTER_VID_UNSPEC)
		efx_filter_set_eth_local(&spec, vlan->vid, NULL);

	rc = efx_ef10_filter_insert(efx, &spec, true);
	rc = efx_ef10_filter_insert_locked(efx, &spec, true);
	if (rc < 0) {
		const char *um = multicast ? "Multicast" : "Unicast";
		const char *encap_name = "";
@@ -5430,7 +5442,7 @@ static int efx_ef10_filter_insert_def(struct efx_nic *efx,
					   filter_flags, 0);
			eth_broadcast_addr(baddr);
			efx_filter_set_eth_local(&spec, vlan->vid, baddr);
			rc = efx_ef10_filter_insert(efx, &spec, true);
			rc = efx_ef10_filter_insert_locked(efx, &spec, true);
			if (rc < 0) {
				netif_warn(efx, drv, efx->net_dev,
					   "Broadcast filter insert failed rc=%d\n",
+8 −9
Original line number Diff line number Diff line
@@ -1871,12 +1871,6 @@ static void efx_remove_filters(struct efx_nic *efx)
	up_write(&efx->filter_sem);
}

static void efx_restore_filters(struct efx_nic *efx)
{
	down_read(&efx->filter_sem);
	efx->type->filter_table_restore(efx);
	up_read(&efx->filter_sem);
}

/**************************************************************************
 *
@@ -2688,6 +2682,7 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method)
	efx_disable_interrupts(efx);

	mutex_lock(&efx->mac_lock);
	down_write(&efx->filter_sem);
	mutex_lock(&efx->rss_lock);
	if (efx->port_initialized && method != RESET_TYPE_INVISIBLE &&
	    method != RESET_TYPE_DATAPATH)
@@ -2745,9 +2740,8 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
	if (efx->type->rx_restore_rss_contexts)
		efx->type->rx_restore_rss_contexts(efx);
	mutex_unlock(&efx->rss_lock);
	down_read(&efx->filter_sem);
	efx_restore_filters(efx);
	up_read(&efx->filter_sem);
	efx->type->filter_table_restore(efx);
	up_write(&efx->filter_sem);
	if (efx->type->sriov_reset)
		efx->type->sriov_reset(efx);

@@ -2764,6 +2758,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
	efx->port_initialized = false;

	mutex_unlock(&efx->rss_lock);
	up_write(&efx->filter_sem);
	mutex_unlock(&efx->mac_lock);

	return rc;
@@ -3473,7 +3468,9 @@ static int efx_pci_probe_main(struct efx_nic *efx)

	efx_init_napi(efx);

	down_write(&efx->filter_sem);
	rc = efx->type->init(efx);
	up_write(&efx->filter_sem);
	if (rc) {
		netif_err(efx, probe, efx->net_dev,
			  "failed to initialise NIC\n");
@@ -3765,7 +3762,9 @@ static int efx_pm_resume(struct device *dev)
	rc = efx->type->reset(efx, RESET_TYPE_ALL);
	if (rc)
		return rc;
	down_write(&efx->filter_sem);
	rc = efx->type->init(efx);
	up_write(&efx->filter_sem);
	if (rc)
		return rc;
	rc = efx_pm_thaw(dev);