Skip to content

Commit e3181e9

Browse files
committed
Merge tag 'mlx5-fixes-2020-05-22' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux
Saeed Mahameed says: ==================== mlx5 fixes 2020-05-22 This series introduces some fixes to mlx5 driver. Please pull and let me know if there is any problem. For -stable v4.13 ('net/mlx5: Add command entry handling completion') For -stable v5.2 ('net/mlx5: Fix error flow in case of function_setup failure') ('net/mlx5: Fix memory leak in mlx5_events_init') For -stable v5.3 ('net/mlx5e: Update netdev txq on completions during closure') ('net/mlx5e: kTLS, Destroy key object after destroying the TIS') ('net/mlx5e: Fix inner tirs handling') For -stable v5.6 ('net/mlx5: Fix cleaning unmanaged flow tables') ('net/mlx5: Fix a race when moving command interface to events mode') ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents febfd9d + 4f7400d commit e3181e9

File tree

16 files changed

+168
-48
lines changed

16 files changed

+168
-48
lines changed

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

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,14 @@ static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg);
848848
static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev,
849849
struct mlx5_cmd_msg *msg);
850850

851+
static bool opcode_allowed(struct mlx5_cmd *cmd, u16 opcode)
852+
{
853+
if (cmd->allowed_opcode == CMD_ALLOWED_OPCODE_ALL)
854+
return true;
855+
856+
return cmd->allowed_opcode == opcode;
857+
}
858+
851859
static void cmd_work_handler(struct work_struct *work)
852860
{
853861
struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work);
@@ -861,6 +869,7 @@ static void cmd_work_handler(struct work_struct *work)
861869
int alloc_ret;
862870
int cmd_mode;
863871

872+
complete(&ent->handling);
864873
sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
865874
down(sem);
866875
if (!ent->page_queue) {
@@ -913,7 +922,9 @@ static void cmd_work_handler(struct work_struct *work)
913922

914923
/* Skip sending command to fw if internal error */
915924
if (pci_channel_offline(dev->pdev) ||
916-
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
925+
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR ||
926+
cmd->state != MLX5_CMDIF_STATE_UP ||
927+
!opcode_allowed(&dev->cmd, ent->op)) {
917928
u8 status = 0;
918929
u32 drv_synd;
919930

@@ -978,19 +989,29 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
978989
struct mlx5_cmd *cmd = &dev->cmd;
979990
int err;
980991

992+
if (!wait_for_completion_timeout(&ent->handling, timeout) &&
993+
cancel_work_sync(&ent->work)) {
994+
ent->ret = -ECANCELED;
995+
goto out_err;
996+
}
981997
if (cmd->mode == CMD_MODE_POLLING || ent->polling) {
982998
wait_for_completion(&ent->done);
983999
} else if (!wait_for_completion_timeout(&ent->done, timeout)) {
9841000
ent->ret = -ETIMEDOUT;
9851001
mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
9861002
}
9871003

1004+
out_err:
9881005
err = ent->ret;
9891006

9901007
if (err == -ETIMEDOUT) {
9911008
mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n",
9921009
mlx5_command_str(msg_to_opcode(ent->in)),
9931010
msg_to_opcode(ent->in));
1011+
} else if (err == -ECANCELED) {
1012+
mlx5_core_warn(dev, "%s(0x%x) canceled on out of queue timeout.\n",
1013+
mlx5_command_str(msg_to_opcode(ent->in)),
1014+
msg_to_opcode(ent->in));
9941015
}
9951016
mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n",
9961017
err, deliv_status_to_str(ent->status), ent->status);
@@ -1026,6 +1047,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
10261047
ent->token = token;
10271048
ent->polling = force_polling;
10281049

1050+
init_completion(&ent->handling);
10291051
if (!callback)
10301052
init_completion(&ent->done);
10311053

@@ -1045,6 +1067,8 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
10451067
err = wait_func(dev, ent);
10461068
if (err == -ETIMEDOUT)
10471069
goto out;
1070+
if (err == -ECANCELED)
1071+
goto out_free;
10481072

10491073
ds = ent->ts2 - ent->ts1;
10501074
op = MLX5_GET(mbox_in, in->first.data, opcode);
@@ -1391,6 +1415,22 @@ static void create_debugfs_files(struct mlx5_core_dev *dev)
13911415
mlx5_cmdif_debugfs_init(dev);
13921416
}
13931417

1418+
void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode)
1419+
{
1420+
struct mlx5_cmd *cmd = &dev->cmd;
1421+
int i;
1422+
1423+
for (i = 0; i < cmd->max_reg_cmds; i++)
1424+
down(&cmd->sem);
1425+
down(&cmd->pages_sem);
1426+
1427+
cmd->allowed_opcode = opcode;
1428+
1429+
up(&cmd->pages_sem);
1430+
for (i = 0; i < cmd->max_reg_cmds; i++)
1431+
up(&cmd->sem);
1432+
}
1433+
13941434
static void mlx5_cmd_change_mod(struct mlx5_core_dev *dev, int mode)
13951435
{
13961436
struct mlx5_cmd *cmd = &dev->cmd;
@@ -1667,12 +1707,14 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
16671707
int err;
16681708
u8 status = 0;
16691709
u32 drv_synd;
1710+
u16 opcode;
16701711
u8 token;
16711712

1713+
opcode = MLX5_GET(mbox_in, in, opcode);
16721714
if (pci_channel_offline(dev->pdev) ||
1673-
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
1674-
u16 opcode = MLX5_GET(mbox_in, in, opcode);
1675-
1715+
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR ||
1716+
dev->cmd.state != MLX5_CMDIF_STATE_UP ||
1717+
!opcode_allowed(&dev->cmd, opcode)) {
16761718
err = mlx5_internal_err_ret_value(dev, opcode, &drv_synd, &status);
16771719
MLX5_SET(mbox_out, out, status, status);
16781720
MLX5_SET(mbox_out, out, syndrome, drv_synd);
@@ -1937,6 +1979,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)
19371979
goto err_free_page;
19381980
}
19391981

1982+
cmd->state = MLX5_CMDIF_STATE_DOWN;
19401983
cmd->checksum_disabled = 1;
19411984
cmd->max_reg_cmds = (1 << cmd->log_sz) - 1;
19421985
cmd->bitmask = (1UL << cmd->max_reg_cmds) - 1;
@@ -1974,6 +2017,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)
19742017
mlx5_core_dbg(dev, "descriptor at dma 0x%llx\n", (unsigned long long)(cmd->dma));
19752018

19762019
cmd->mode = CMD_MODE_POLLING;
2020+
cmd->allowed_opcode = CMD_ALLOWED_OPCODE_ALL;
19772021

19782022
create_msg_cache(dev);
19792023

@@ -2013,3 +2057,10 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev)
20132057
dma_pool_destroy(cmd->pool);
20142058
}
20152059
EXPORT_SYMBOL(mlx5_cmd_cleanup);
2060+
2061+
void mlx5_cmd_set_state(struct mlx5_core_dev *dev,
2062+
enum mlx5_cmdif_state cmdif_state)
2063+
{
2064+
dev->cmd.state = cmdif_state;
2065+
}
2066+
EXPORT_SYMBOL(mlx5_cmd_set_state);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,7 @@ void mlx5e_close_drop_rq(struct mlx5e_rq *drop_rq);
11211121
int mlx5e_create_indirect_rqt(struct mlx5e_priv *priv);
11221122

11231123
int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc);
1124-
void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc);
1124+
void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv);
11251125

11261126
int mlx5e_create_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs);
11271127
void mlx5e_destroy_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs);

drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -699,14 +699,15 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
699699
struct netlink_ext_ack *extack)
700700
{
701701
struct mlx5_tc_ct_priv *ct_priv = mlx5_tc_ct_get_ct_priv(priv);
702+
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
702703
struct flow_dissector_key_ct *mask, *key;
703704
bool trk, est, untrk, unest, new;
704705
u32 ctstate = 0, ctstate_mask = 0;
705706
u16 ct_state_on, ct_state_off;
706707
u16 ct_state, ct_state_mask;
707708
struct flow_match_ct match;
708709

709-
if (!flow_rule_match_key(f->rule, FLOW_DISSECTOR_KEY_CT))
710+
if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
710711
return 0;
711712

712713
if (!ct_priv) {
@@ -715,7 +716,7 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
715716
return -EOPNOTSUPP;
716717
}
717718

718-
flow_rule_match_ct(f->rule, &match);
719+
flow_rule_match_ct(rule, &match);
719720

720721
key = match.key;
721722
mask = match.mask;

drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
130130
struct flow_cls_offload *f,
131131
struct netlink_ext_ack *extack)
132132
{
133-
if (!flow_rule_match_key(f->rule, FLOW_DISSECTOR_KEY_CT))
133+
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
134+
135+
if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
134136
return 0;
135137

136138
NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ static void mlx5e_ktls_del(struct net_device *netdev,
6969
struct mlx5e_ktls_offload_context_tx *tx_priv =
7070
mlx5e_get_ktls_tx_priv_ctx(tls_ctx);
7171

72-
mlx5_ktls_destroy_key(priv->mdev, tx_priv->key_id);
7372
mlx5e_destroy_tis(priv->mdev, tx_priv->tisn);
73+
mlx5_ktls_destroy_key(priv->mdev, tx_priv->key_id);
7474
kvfree(tx_priv);
7575
}
7676

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2717,7 +2717,8 @@ void mlx5e_modify_tirs_hash(struct mlx5e_priv *priv, void *in, int inlen)
27172717
mlx5_core_modify_tir(mdev, priv->indir_tir[tt].tirn, in, inlen);
27182718
}
27192719

2720-
if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
2720+
/* Verify inner tirs resources allocated */
2721+
if (!priv->inner_indir_tir[0].tirn)
27212722
return;
27222723

27232724
for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
@@ -3408,14 +3409,15 @@ int mlx5e_create_direct_tirs(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
34083409
return err;
34093410
}
34103411

3411-
void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc)
3412+
void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv)
34123413
{
34133414
int i;
34143415

34153416
for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++)
34163417
mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[i]);
34173418

3418-
if (!inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev))
3419+
/* Verify inner tirs resources allocated */
3420+
if (!priv->inner_indir_tir[0].tirn)
34193421
return;
34203422

34213423
for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++)
@@ -5123,7 +5125,7 @@ static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
51235125
err_destroy_direct_tirs:
51245126
mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
51255127
err_destroy_indirect_tirs:
5126-
mlx5e_destroy_indirect_tirs(priv, true);
5128+
mlx5e_destroy_indirect_tirs(priv);
51275129
err_destroy_direct_rqts:
51285130
mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
51295131
err_destroy_indirect_rqts:
@@ -5142,7 +5144,7 @@ static void mlx5e_cleanup_nic_rx(struct mlx5e_priv *priv)
51425144
mlx5e_destroy_direct_tirs(priv, priv->xsk_tir);
51435145
mlx5e_destroy_direct_rqts(priv, priv->xsk_tir);
51445146
mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
5145-
mlx5e_destroy_indirect_tirs(priv, true);
5147+
mlx5e_destroy_indirect_tirs(priv);
51465148
mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
51475149
mlx5e_destroy_rqt(priv, &priv->indir_rqt);
51485150
mlx5e_close_drop_rq(&priv->drop_rq);

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

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,13 +1484,9 @@ bool mlx5e_eswitch_uplink_rep(struct net_device *netdev)
14841484
return netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep;
14851485
}
14861486

1487-
bool mlx5e_eswitch_rep(struct net_device *netdev)
1487+
bool mlx5e_eswitch_vf_rep(struct net_device *netdev)
14881488
{
1489-
if (netdev->netdev_ops == &mlx5e_netdev_ops_rep ||
1490-
netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep)
1491-
return true;
1492-
1493-
return false;
1489+
return netdev->netdev_ops == &mlx5e_netdev_ops_rep;
14941490
}
14951491

14961492
static void mlx5e_build_rep_params(struct net_device *netdev)
@@ -1747,7 +1743,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
17471743
err_destroy_direct_tirs:
17481744
mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
17491745
err_destroy_indirect_tirs:
1750-
mlx5e_destroy_indirect_tirs(priv, false);
1746+
mlx5e_destroy_indirect_tirs(priv);
17511747
err_destroy_direct_rqts:
17521748
mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
17531749
err_destroy_indirect_rqts:
@@ -1765,7 +1761,7 @@ static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
17651761
mlx5e_destroy_rep_root_ft(priv);
17661762
mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
17671763
mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
1768-
mlx5e_destroy_indirect_tirs(priv, false);
1764+
mlx5e_destroy_indirect_tirs(priv);
17691765
mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
17701766
mlx5e_destroy_rqt(priv, &priv->indir_rqt);
17711767
mlx5e_close_drop_rq(&priv->drop_rq);

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,13 @@ void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv,
210210

211211
void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv);
212212

213-
bool mlx5e_eswitch_rep(struct net_device *netdev);
213+
bool mlx5e_eswitch_vf_rep(struct net_device *netdev);
214214
bool mlx5e_eswitch_uplink_rep(struct net_device *netdev);
215+
static inline bool mlx5e_eswitch_rep(struct net_device *netdev)
216+
{
217+
return mlx5e_eswitch_vf_rep(netdev) ||
218+
mlx5e_eswitch_uplink_rep(netdev);
219+
}
215220

216221
#else /* CONFIG_MLX5_ESWITCH */
217222
static inline bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv) { return false; }

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

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3073,6 +3073,11 @@ static bool actions_match_supported(struct mlx5e_priv *priv,
30733073
return true;
30743074
}
30753075

3076+
static bool same_port_devs(struct mlx5e_priv *priv, struct mlx5e_priv *peer_priv)
3077+
{
3078+
return priv->mdev == peer_priv->mdev;
3079+
}
3080+
30763081
static bool same_hw_devs(struct mlx5e_priv *priv, struct mlx5e_priv *peer_priv)
30773082
{
30783083
struct mlx5_core_dev *fmdev, *pmdev;
@@ -3291,21 +3296,19 @@ static inline int hash_encap_info(struct encap_key *key)
32913296
}
32923297

32933298

3294-
static bool is_merged_eswitch_dev(struct mlx5e_priv *priv,
3299+
static bool is_merged_eswitch_vfs(struct mlx5e_priv *priv,
32953300
struct net_device *peer_netdev)
32963301
{
32973302
struct mlx5e_priv *peer_priv;
32983303

32993304
peer_priv = netdev_priv(peer_netdev);
33003305

33013306
return (MLX5_CAP_ESW(priv->mdev, merged_eswitch) &&
3302-
mlx5e_eswitch_rep(priv->netdev) &&
3303-
mlx5e_eswitch_rep(peer_netdev) &&
3307+
mlx5e_eswitch_vf_rep(priv->netdev) &&
3308+
mlx5e_eswitch_vf_rep(peer_netdev) &&
33043309
same_hw_devs(priv, peer_priv));
33053310
}
33063311

3307-
3308-
33093312
bool mlx5e_encap_take(struct mlx5e_encap_entry *e)
33103313
{
33113314
return refcount_inc_not_zero(&e->refcnt);
@@ -3575,14 +3578,37 @@ static int add_vlan_pop_action(struct mlx5e_priv *priv,
35753578
return err;
35763579
}
35773580

3581+
static bool same_hw_reps(struct mlx5e_priv *priv,
3582+
struct net_device *peer_netdev)
3583+
{
3584+
struct mlx5e_priv *peer_priv;
3585+
3586+
peer_priv = netdev_priv(peer_netdev);
3587+
3588+
return mlx5e_eswitch_rep(priv->netdev) &&
3589+
mlx5e_eswitch_rep(peer_netdev) &&
3590+
same_hw_devs(priv, peer_priv);
3591+
}
3592+
3593+
static bool is_lag_dev(struct mlx5e_priv *priv,
3594+
struct net_device *peer_netdev)
3595+
{
3596+
return ((mlx5_lag_is_sriov(priv->mdev) ||
3597+
mlx5_lag_is_multipath(priv->mdev)) &&
3598+
same_hw_reps(priv, peer_netdev));
3599+
}
3600+
35783601
bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv,
35793602
struct net_device *out_dev)
35803603
{
3581-
if (is_merged_eswitch_dev(priv, out_dev))
3604+
if (is_merged_eswitch_vfs(priv, out_dev))
3605+
return true;
3606+
3607+
if (is_lag_dev(priv, out_dev))
35823608
return true;
35833609

35843610
return mlx5e_eswitch_rep(out_dev) &&
3585-
same_hw_devs(priv, netdev_priv(out_dev));
3611+
same_port_devs(priv, netdev_priv(out_dev));
35863612
}
35873613

35883614
static bool is_duplicated_output_device(struct net_device *dev,

0 commit comments

Comments
 (0)