Commit 77eb4074 authored by Edward Cree's avatar Edward Cree Committed by Jakub Kicinski
Browse files

sfc: move table locking into filter_table_{probe,remove} methods



We need to be able to drop the efx->filter_sem in ef100_filter_table_up()
 so that we can call functions that insert filters (and thus take that
 rwsem for read), which means the efx->type->filter_table_probe method
 needs to be responsible for taking the lock in the first place.

Signed-off-by: default avatarEdward Cree <ecree.xilinx@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 67ab160e
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -2538,23 +2538,33 @@ static int efx_ef10_filter_table_probe(struct efx_nic *efx)

	if (rc)
		return rc;
	down_write(&efx->filter_sem);
	rc = efx_mcdi_filter_table_probe(efx, nic_data->workaround_26807);

	if (rc)
		return rc;
		goto out_unlock;

	list_for_each_entry(vlan, &nic_data->vlan_list, list) {
		rc = efx_mcdi_filter_add_vlan(efx, vlan->vid);
		if (rc)
			goto fail_add_vlan;
	}
	return 0;
	goto out_unlock;

fail_add_vlan:
	efx_mcdi_filter_table_remove(efx);
out_unlock:
	up_write(&efx->filter_sem);
	return rc;
}

static void efx_ef10_filter_table_remove(struct efx_nic *efx)
{
	down_write(&efx->filter_sem);
	efx_mcdi_filter_table_remove(efx);
	up_write(&efx->filter_sem);
}

/* This creates an entry in the RX descriptor queue */
static inline void
efx_ef10_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index)
@@ -3211,9 +3221,7 @@ static int efx_ef10_vport_set_mac_address(struct efx_nic *efx)

	efx_device_detach_sync(efx);
	efx_net_stop(efx->net_dev);
	down_write(&efx->filter_sem);
	efx_mcdi_filter_table_remove(efx);
	up_write(&efx->filter_sem);
	efx_ef10_filter_table_remove(efx);

	rc = efx_ef10_vadaptor_free(efx, efx->vport_id);
	if (rc)
@@ -3243,9 +3251,7 @@ static int efx_ef10_vport_set_mac_address(struct efx_nic *efx)
	if (rc2)
		goto reset_nic;
restore_filters:
	down_write(&efx->filter_sem);
	rc2 = efx_ef10_filter_table_probe(efx);
	up_write(&efx->filter_sem);
	if (rc2)
		goto reset_nic;

@@ -3275,8 +3281,7 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
	efx_net_stop(efx->net_dev);

	mutex_lock(&efx->mac_lock);
	down_write(&efx->filter_sem);
	efx_mcdi_filter_table_remove(efx);
	efx_ef10_filter_table_remove(efx);

	ether_addr_copy(MCDI_PTR(inbuf, VADAPTOR_SET_MAC_IN_MACADDR),
			efx->net_dev->dev_addr);
@@ -3286,7 +3291,6 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
				sizeof(inbuf), NULL, 0, NULL);

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

	if (was_enabled)
@@ -4092,7 +4096,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
	.ev_test_generate = efx_ef10_ev_test_generate,
	.filter_table_probe = efx_ef10_filter_table_probe,
	.filter_table_restore = efx_mcdi_filter_table_restore,
	.filter_table_remove = efx_mcdi_filter_table_remove,
	.filter_table_remove = efx_ef10_filter_table_remove,
	.filter_update_rx_scatter = efx_mcdi_update_rx_scatter,
	.filter_insert = efx_mcdi_filter_insert,
	.filter_remove_safe = efx_mcdi_filter_remove_safe,
+14 −8
Original line number Diff line number Diff line
@@ -375,26 +375,32 @@ static int ef100_filter_table_up(struct efx_nic *efx)
{
	int rc;

	down_write(&efx->filter_sem);
	rc = efx_mcdi_filter_add_vlan(efx, EFX_FILTER_VID_UNSPEC);
	if (rc) {
		efx_mcdi_filter_table_down(efx);
		return rc;
	}
	if (rc)
		goto fail_unspec;

	rc = efx_mcdi_filter_add_vlan(efx, 0);
	if (rc) {
	if (rc)
		goto fail_vlan0;
	up_write(&efx->filter_sem);
	return 0;

fail_vlan0:
	efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
fail_unspec:
	efx_mcdi_filter_table_down(efx);
	}

	up_write(&efx->filter_sem);
	return rc;
}

static void ef100_filter_table_down(struct efx_nic *efx)
{
	down_write(&efx->filter_sem);
	efx_mcdi_filter_del_vlan(efx, 0);
	efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
	efx_mcdi_filter_table_down(efx);
	up_write(&efx->filter_sem);
}

/*	Other
+3 −13
Original line number Diff line number Diff line
@@ -501,15 +501,12 @@ int efx_ef10_sriov_set_vf_mac(struct efx_nic *efx, int vf_i, const u8 *mac)
		efx_device_detach_sync(vf->efx);
		efx_net_stop(vf->efx->net_dev);

		down_write(&vf->efx->filter_sem);
		vf->efx->type->filter_table_remove(vf->efx);

		rc = efx_ef10_vadaptor_free(vf->efx, EVB_PORT_ID_ASSIGNED);
		if (rc) {
			up_write(&vf->efx->filter_sem);
		if (rc)
			return rc;
	}
	}

	rc = efx_ef10_evb_port_assign(efx, EVB_PORT_ID_NULL, vf_i);
	if (rc)
@@ -539,12 +536,9 @@ int efx_ef10_sriov_set_vf_mac(struct efx_nic *efx, int vf_i, const u8 *mac)
	if (vf->efx) {
		/* VF cannot use the vport_id that the PF created */
		rc = efx_ef10_vadaptor_alloc(vf->efx, EVB_PORT_ID_ASSIGNED);
		if (rc) {
			up_write(&vf->efx->filter_sem);
		if (rc)
			return rc;
		}
		vf->efx->type->filter_table_probe(vf->efx);
		up_write(&vf->efx->filter_sem);
		efx_net_open(vf->efx->net_dev);
		efx_device_attach_if_not_resetting(vf->efx);
	}
@@ -580,7 +574,6 @@ int efx_ef10_sriov_set_vf_vlan(struct efx_nic *efx, int vf_i, u16 vlan,
		efx_net_stop(vf->efx->net_dev);

		mutex_lock(&vf->efx->mac_lock);
		down_write(&vf->efx->filter_sem);
		vf->efx->type->filter_table_remove(vf->efx);

		rc = efx_ef10_vadaptor_free(vf->efx, EVB_PORT_ID_ASSIGNED);
@@ -654,7 +647,6 @@ int efx_ef10_sriov_set_vf_vlan(struct efx_nic *efx, int vf_i, u16 vlan,
		if (rc2)
			goto reset_nic_up_write;

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

		rc2 = efx_net_open(vf->efx->net_dev);
@@ -666,10 +658,8 @@ int efx_ef10_sriov_set_vf_vlan(struct efx_nic *efx, int vf_i, u16 vlan,
	return rc;

reset_nic_up_write:
	if (vf->efx) {
		up_write(&vf->efx->filter_sem);
	if (vf->efx)
		mutex_unlock(&vf->efx->mac_lock);
	}
reset_nic:
	if (vf->efx) {
		netif_err(efx, drv, efx->net_dev,
+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ struct efx_mcdi_filter_table {
	 */
	bool mc_chaining;
	bool vlan_filter;
	/* Entries on the vlan_list are added/removed under filter_sem */
	struct list_head vlan_list;
};

+0 −4
Original line number Diff line number Diff line
@@ -793,7 +793,6 @@ int efx_probe_filters(struct efx_nic *efx)
	int rc;

	mutex_lock(&efx->mac_lock);
	down_write(&efx->filter_sem);
	rc = efx->type->filter_table_probe(efx);
	if (rc)
		goto out_unlock;
@@ -830,7 +829,6 @@ int efx_probe_filters(struct efx_nic *efx)
	}
#endif
out_unlock:
	up_write(&efx->filter_sem);
	mutex_unlock(&efx->mac_lock);
	return rc;
}
@@ -846,9 +844,7 @@ void efx_remove_filters(struct efx_nic *efx)
		channel->rps_flow_id = NULL;
	}
#endif
	down_write(&efx->filter_sem);
	efx->type->filter_table_remove(efx);
	up_write(&efx->filter_sem);
}

#ifdef CONFIG_RFS_ACCEL