Skip to content

Commit 77eb407

Browse files
Edward Creekuba-moo
authored andcommitted
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: Edward Cree <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 67ab160 commit 77eb407

File tree

5 files changed

+33
-36
lines changed

5 files changed

+33
-36
lines changed

drivers/net/ethernet/sfc/ef10.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2538,23 +2538,33 @@ static int efx_ef10_filter_table_probe(struct efx_nic *efx)
25382538

25392539
if (rc)
25402540
return rc;
2541+
down_write(&efx->filter_sem);
25412542
rc = efx_mcdi_filter_table_probe(efx, nic_data->workaround_26807);
25422543

25432544
if (rc)
2544-
return rc;
2545+
goto out_unlock;
25452546

25462547
list_for_each_entry(vlan, &nic_data->vlan_list, list) {
25472548
rc = efx_mcdi_filter_add_vlan(efx, vlan->vid);
25482549
if (rc)
25492550
goto fail_add_vlan;
25502551
}
2551-
return 0;
2552+
goto out_unlock;
25522553

25532554
fail_add_vlan:
25542555
efx_mcdi_filter_table_remove(efx);
2556+
out_unlock:
2557+
up_write(&efx->filter_sem);
25552558
return rc;
25562559
}
25572560

2561+
static void efx_ef10_filter_table_remove(struct efx_nic *efx)
2562+
{
2563+
down_write(&efx->filter_sem);
2564+
efx_mcdi_filter_table_remove(efx);
2565+
up_write(&efx->filter_sem);
2566+
}
2567+
25582568
/* This creates an entry in the RX descriptor queue */
25592569
static inline void
25602570
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)
32113221

32123222
efx_device_detach_sync(efx);
32133223
efx_net_stop(efx->net_dev);
3214-
down_write(&efx->filter_sem);
3215-
efx_mcdi_filter_table_remove(efx);
3216-
up_write(&efx->filter_sem);
3224+
efx_ef10_filter_table_remove(efx);
32173225

32183226
rc = efx_ef10_vadaptor_free(efx, efx->vport_id);
32193227
if (rc)
@@ -3243,9 +3251,7 @@ static int efx_ef10_vport_set_mac_address(struct efx_nic *efx)
32433251
if (rc2)
32443252
goto reset_nic;
32453253
restore_filters:
3246-
down_write(&efx->filter_sem);
32473254
rc2 = efx_ef10_filter_table_probe(efx);
3248-
up_write(&efx->filter_sem);
32493255
if (rc2)
32503256
goto reset_nic;
32513257

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

32773283
mutex_lock(&efx->mac_lock);
3278-
down_write(&efx->filter_sem);
3279-
efx_mcdi_filter_table_remove(efx);
3284+
efx_ef10_filter_table_remove(efx);
32803285

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

32883293
efx_ef10_filter_table_probe(efx);
3289-
up_write(&efx->filter_sem);
32903294
mutex_unlock(&efx->mac_lock);
32913295

32923296
if (was_enabled)
@@ -4092,7 +4096,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
40924096
.ev_test_generate = efx_ef10_ev_test_generate,
40934097
.filter_table_probe = efx_ef10_filter_table_probe,
40944098
.filter_table_restore = efx_mcdi_filter_table_restore,
4095-
.filter_table_remove = efx_mcdi_filter_table_remove,
4099+
.filter_table_remove = efx_ef10_filter_table_remove,
40964100
.filter_update_rx_scatter = efx_mcdi_update_rx_scatter,
40974101
.filter_insert = efx_mcdi_filter_insert,
40984102
.filter_remove_safe = efx_mcdi_filter_remove_safe,

drivers/net/ethernet/sfc/ef100_nic.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -375,26 +375,32 @@ static int ef100_filter_table_up(struct efx_nic *efx)
375375
{
376376
int rc;
377377

378+
down_write(&efx->filter_sem);
378379
rc = efx_mcdi_filter_add_vlan(efx, EFX_FILTER_VID_UNSPEC);
379-
if (rc) {
380-
efx_mcdi_filter_table_down(efx);
381-
return rc;
382-
}
380+
if (rc)
381+
goto fail_unspec;
383382

384383
rc = efx_mcdi_filter_add_vlan(efx, 0);
385-
if (rc) {
386-
efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
387-
efx_mcdi_filter_table_down(efx);
388-
}
384+
if (rc)
385+
goto fail_vlan0;
386+
up_write(&efx->filter_sem);
387+
return 0;
389388

389+
fail_vlan0:
390+
efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
391+
fail_unspec:
392+
efx_mcdi_filter_table_down(efx);
393+
up_write(&efx->filter_sem);
390394
return rc;
391395
}
392396

393397
static void ef100_filter_table_down(struct efx_nic *efx)
394398
{
399+
down_write(&efx->filter_sem);
395400
efx_mcdi_filter_del_vlan(efx, 0);
396401
efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
397402
efx_mcdi_filter_table_down(efx);
403+
up_write(&efx->filter_sem);
398404
}
399405

400406
/* Other

drivers/net/ethernet/sfc/ef10_sriov.c

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -501,14 +501,11 @@ int efx_ef10_sriov_set_vf_mac(struct efx_nic *efx, int vf_i, const u8 *mac)
501501
efx_device_detach_sync(vf->efx);
502502
efx_net_stop(vf->efx->net_dev);
503503

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

507506
rc = efx_ef10_vadaptor_free(vf->efx, EVB_PORT_ID_ASSIGNED);
508-
if (rc) {
509-
up_write(&vf->efx->filter_sem);
507+
if (rc)
510508
return rc;
511-
}
512509
}
513510

514511
rc = efx_ef10_evb_port_assign(efx, EVB_PORT_ID_NULL, vf_i);
@@ -539,12 +536,9 @@ int efx_ef10_sriov_set_vf_mac(struct efx_nic *efx, int vf_i, const u8 *mac)
539536
if (vf->efx) {
540537
/* VF cannot use the vport_id that the PF created */
541538
rc = efx_ef10_vadaptor_alloc(vf->efx, EVB_PORT_ID_ASSIGNED);
542-
if (rc) {
543-
up_write(&vf->efx->filter_sem);
539+
if (rc)
544540
return rc;
545-
}
546541
vf->efx->type->filter_table_probe(vf->efx);
547-
up_write(&vf->efx->filter_sem);
548542
efx_net_open(vf->efx->net_dev);
549543
efx_device_attach_if_not_resetting(vf->efx);
550544
}
@@ -580,7 +574,6 @@ int efx_ef10_sriov_set_vf_vlan(struct efx_nic *efx, int vf_i, u16 vlan,
580574
efx_net_stop(vf->efx->net_dev);
581575

582576
mutex_lock(&vf->efx->mac_lock);
583-
down_write(&vf->efx->filter_sem);
584577
vf->efx->type->filter_table_remove(vf->efx);
585578

586579
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,
654647
if (rc2)
655648
goto reset_nic_up_write;
656649

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

660652
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,
666658
return rc;
667659

668660
reset_nic_up_write:
669-
if (vf->efx) {
670-
up_write(&vf->efx->filter_sem);
661+
if (vf->efx)
671662
mutex_unlock(&vf->efx->mac_lock);
672-
}
673663
reset_nic:
674664
if (vf->efx) {
675665
netif_err(efx, drv, efx->net_dev,

drivers/net/ethernet/sfc/mcdi_filters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ struct efx_mcdi_filter_table {
8989
*/
9090
bool mc_chaining;
9191
bool vlan_filter;
92+
/* Entries on the vlan_list are added/removed under filter_sem */
9293
struct list_head vlan_list;
9394
};
9495

drivers/net/ethernet/sfc/rx_common.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,6 @@ int efx_probe_filters(struct efx_nic *efx)
793793
int rc;
794794

795795
mutex_lock(&efx->mac_lock);
796-
down_write(&efx->filter_sem);
797796
rc = efx->type->filter_table_probe(efx);
798797
if (rc)
799798
goto out_unlock;
@@ -830,7 +829,6 @@ int efx_probe_filters(struct efx_nic *efx)
830829
}
831830
#endif
832831
out_unlock:
833-
up_write(&efx->filter_sem);
834832
mutex_unlock(&efx->mac_lock);
835833
return rc;
836834
}
@@ -846,9 +844,7 @@ void efx_remove_filters(struct efx_nic *efx)
846844
channel->rps_flow_id = NULL;
847845
}
848846
#endif
849-
down_write(&efx->filter_sem);
850847
efx->type->filter_table_remove(efx);
851-
up_write(&efx->filter_sem);
852848
}
853849

854850
#ifdef CONFIG_RFS_ACCEL

0 commit comments

Comments
 (0)