Skip to content

Commit f4d3391

Browse files
shayshyiBrian Maly
authored andcommitted
net/mlx5: Handle pairing of E-switch via uplink un/load APIs
In case user switch a device from switchdev mode to legacy mode, mlx5 first unpair the E-switch and afterwards unload the uplink vport. From the other hand, in case user remove or reload a device, mlx5 first unload the uplink vport and afterwards unpair the E-switch. The latter is causing a bug[1], hence, handle pairing of E-switch as part of uplink un/load APIs. [1] In case VF_LAG is used, every tc fdb flow is duplicated to the peer esw. However, the original esw keeps a pointer to this duplicated flow, not the peer esw. e.g.: if user create tc fdb flow over esw0, the flow is duplicated over esw1, in FW/HW, but in SW, esw0 keeps a pointer to the duplicated flow. During module unload while a peer tc fdb flow is still offloaded, in case the first device to be removed is the peer device (esw1 in the example above), the peer net-dev is destroyed, and so the mlx5e_priv is memset to 0. Afterwards, the peer device is trying to unpair himself from the original device (esw0 in the example above). Unpair API invoke the original device to clear peer flow from its eswitch (esw0), but the peer flow, which is stored over the original eswitch (esw0), is trying to use the peer mlx5e_priv, which is memset to 0 and result in bellow kernel-oops. [ 157.964081 ] BUG: unable to handle page fault for address: 000000000002ce60 [ 157.964662 ] #PF: supervisor read access in kernel mode [ 157.965123 ] #PF: error_code(0x0000) - not-present page [ 157.965582 ] PGD 0 P4D 0 [ 157.965866 ] Oops: 0000 [#1] SMP [ 157.967670 ] RIP: 0010:mlx5e_tc_del_fdb_flow+0x48/0x460 [mlx5_core] [ 157.976164 ] Call Trace: [ 157.976437 ] <TASK> [ 157.976690 ] __mlx5e_tc_del_fdb_peer_flow+0xe6/0x100 [mlx5_core] [ 157.977230 ] mlx5e_tc_clean_fdb_peer_flows+0x67/0x90 [mlx5_core] [ 157.977767 ] mlx5_esw_offloads_unpair+0x2d/0x1e0 [mlx5_core] [ 157.984653 ] mlx5_esw_offloads_devcom_event+0xbf/0x130 [mlx5_core] [ 157.985212 ] mlx5_devcom_send_event+0xa3/0xb0 [mlx5_core] [ 157.985714 ] esw_offloads_disable+0x5a/0x110 [mlx5_core] [ 157.986209 ] mlx5_eswitch_disable_locked+0x152/0x170 [mlx5_core] [ 157.986757 ] mlx5_eswitch_disable+0x51/0x80 [mlx5_core] [ 157.987248 ] mlx5_unload+0x2a/0xb0 [mlx5_core] [ 157.987678 ] mlx5_uninit_one+0x5f/0xd0 [mlx5_core] [ 157.988127 ] remove_one+0x64/0xe0 [mlx5_core] [ 157.988549 ] pci_device_remove+0x31/0xa0 [ 157.988933 ] device_release_driver_internal+0x18f/0x1f0 [ 157.989402 ] driver_detach+0x3f/0x80 [ 157.989754 ] bus_remove_driver+0x70/0xf0 [ 157.990129 ] pci_unregister_driver+0x34/0x90 [ 157.990537 ] mlx5_cleanup+0xc/0x1c [mlx5_core] [ 157.990972 ] __x64_sys_delete_module+0x15a/0x250 [ 157.991398 ] ? exit_to_user_mode_prepare+0xea/0x110 [ 157.991840 ] do_syscall_64+0x3d/0x90 [ 157.992198 ] entry_SYSCALL_64_after_hwframe+0x46/0xb0 Fixes: 04de7dd ("net/mlx5e: Infrastructure for duplicated offloading of TC flows") Fixes: 1418ddd ("net/mlx5e: Duplicate offloaded TC eswitch rules under uplink LAG") Signed-off-by: Shay Drory <[email protected]> Reviewed-by: Roi Dayan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]> Orabug: 35383105 (cherry picked from commit 2be5bd4) cherry-pick-repo=kernel/git/torvalds/linux.git unmodified-from-upstream: 2be5bd4 Signed-off-by: Mikhael Goikhman <[email protected]> Signed-off-by: Qing Huang <[email protected]> Reviewed-by: Devesh Sharma <[email protected]> Signed-off-by: Brian Maly <[email protected]>
1 parent 04d2e26 commit f4d3391

File tree

3 files changed

+9
-6
lines changed

3 files changed

+9
-6
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5311,6 +5311,8 @@ int mlx5e_tc_esw_init(struct mlx5_rep_uplink_priv *uplink_priv)
53115311
goto err_action_counter;
53125312
}
53135313

5314+
mlx5_esw_offloads_devcom_init(esw);
5315+
53145316
return 0;
53155317

53165318
err_action_counter:
@@ -5339,7 +5341,7 @@ void mlx5e_tc_esw_cleanup(struct mlx5_rep_uplink_priv *uplink_priv)
53395341
priv = netdev_priv(rpriv->netdev);
53405342
esw = priv->mdev->priv.eswitch;
53415343

5342-
mlx5e_tc_clean_fdb_peer_flows(esw);
5344+
mlx5_esw_offloads_devcom_cleanup(esw);
53435345

53445346
mlx5e_tc_tun_cleanup(uplink_priv->encap);
53455347

drivers/net/ethernet/mellanox/mlx5/core/eswitch.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,8 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs);
369369
void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf);
370370
void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw);
371371
void mlx5_eswitch_disable(struct mlx5_eswitch *esw);
372+
void mlx5_esw_offloads_devcom_init(struct mlx5_eswitch *esw);
373+
void mlx5_esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw);
372374
int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
373375
u16 vport, const u8 *mac);
374376
int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
@@ -767,6 +769,8 @@ static inline void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) {}
767769
static inline int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) { return 0; }
768770
static inline void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf) {}
769771
static inline void mlx5_eswitch_disable(struct mlx5_eswitch *esw) {}
772+
static inline void mlx5_esw_offloads_devcom_init(struct mlx5_eswitch *esw) {}
773+
static inline void mlx5_esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw) {}
770774
static inline bool mlx5_eswitch_is_funcs_handler(struct mlx5_core_dev *dev) { return false; }
771775
static inline
772776
int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, u16 vport, int link_state) { return 0; }

drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2781,7 +2781,7 @@ static int mlx5_esw_offloads_devcom_event(int event,
27812781
return err;
27822782
}
27832783

2784-
static void esw_offloads_devcom_init(struct mlx5_eswitch *esw)
2784+
void mlx5_esw_offloads_devcom_init(struct mlx5_eswitch *esw)
27852785
{
27862786
struct mlx5_devcom *devcom = esw->dev->priv.devcom;
27872787

@@ -2804,7 +2804,7 @@ static void esw_offloads_devcom_init(struct mlx5_eswitch *esw)
28042804
ESW_OFFLOADS_DEVCOM_PAIR, esw);
28052805
}
28062806

2807-
static void esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw)
2807+
void mlx5_esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw)
28082808
{
28092809
struct mlx5_devcom *devcom = esw->dev->priv.devcom;
28102810

@@ -3256,8 +3256,6 @@ int esw_offloads_enable(struct mlx5_eswitch *esw)
32563256
if (err)
32573257
goto err_vports;
32583258

3259-
esw_offloads_devcom_init(esw);
3260-
32613259
return 0;
32623260

32633261
err_vports:
@@ -3298,7 +3296,6 @@ static int esw_offloads_stop(struct mlx5_eswitch *esw,
32983296

32993297
void esw_offloads_disable(struct mlx5_eswitch *esw)
33003298
{
3301-
esw_offloads_devcom_cleanup(esw);
33023299
mlx5_eswitch_disable_pf_vf_vports(esw);
33033300
esw_offloads_unload_rep(esw, MLX5_VPORT_UPLINK);
33043301
esw_set_passing_vport_metadata(esw, false);

0 commit comments

Comments
 (0)