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

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: default avatarDavid S. Miller <davem@davemloft.net>
parents febfd9d3 4f7400d5
Loading
Loading
Loading
Loading
+55 −4
Original line number Diff line number Diff line
@@ -848,6 +848,14 @@ static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg);
static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev,
			      struct mlx5_cmd_msg *msg);

static bool opcode_allowed(struct mlx5_cmd *cmd, u16 opcode)
{
	if (cmd->allowed_opcode == CMD_ALLOWED_OPCODE_ALL)
		return true;

	return cmd->allowed_opcode == opcode;
}

static void cmd_work_handler(struct work_struct *work)
{
	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)
	int alloc_ret;
	int cmd_mode;

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

	/* Skip sending command to fw if internal error */
	if (pci_channel_offline(dev->pdev) ||
	    dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
	    dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR ||
	    cmd->state != MLX5_CMDIF_STATE_UP ||
	    !opcode_allowed(&dev->cmd, ent->op)) {
		u8 status = 0;
		u32 drv_synd;

@@ -978,6 +989,11 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
	struct mlx5_cmd *cmd = &dev->cmd;
	int err;

	if (!wait_for_completion_timeout(&ent->handling, timeout) &&
	    cancel_work_sync(&ent->work)) {
		ent->ret = -ECANCELED;
		goto out_err;
	}
	if (cmd->mode == CMD_MODE_POLLING || ent->polling) {
		wait_for_completion(&ent->done);
	} else if (!wait_for_completion_timeout(&ent->done, timeout)) {
@@ -985,12 +1001,17 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
		mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
	}

out_err:
	err = ent->ret;

	if (err == -ETIMEDOUT) {
		mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n",
			       mlx5_command_str(msg_to_opcode(ent->in)),
			       msg_to_opcode(ent->in));
	} else if (err == -ECANCELED) {
		mlx5_core_warn(dev, "%s(0x%x) canceled on out of queue timeout.\n",
			       mlx5_command_str(msg_to_opcode(ent->in)),
			       msg_to_opcode(ent->in));
	}
	mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n",
		      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,
	ent->token = token;
	ent->polling = force_polling;

	init_completion(&ent->handling);
	if (!callback)
		init_completion(&ent->done);

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

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

void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode)
{
	struct mlx5_cmd *cmd = &dev->cmd;
	int i;

	for (i = 0; i < cmd->max_reg_cmds; i++)
		down(&cmd->sem);
	down(&cmd->pages_sem);

	cmd->allowed_opcode = opcode;

	up(&cmd->pages_sem);
	for (i = 0; i < cmd->max_reg_cmds; i++)
		up(&cmd->sem);
}

static void mlx5_cmd_change_mod(struct mlx5_core_dev *dev, int mode)
{
	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,
	int err;
	u8 status = 0;
	u32 drv_synd;
	u16 opcode;
	u8 token;

	opcode = MLX5_GET(mbox_in, in, opcode);
	if (pci_channel_offline(dev->pdev) ||
	    dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
		u16 opcode = MLX5_GET(mbox_in, in, opcode);

	    dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR ||
	    dev->cmd.state != MLX5_CMDIF_STATE_UP ||
	    !opcode_allowed(&dev->cmd, opcode)) {
		err = mlx5_internal_err_ret_value(dev, opcode, &drv_synd, &status);
		MLX5_SET(mbox_out, out, status, status);
		MLX5_SET(mbox_out, out, syndrome, drv_synd);
@@ -1937,6 +1979,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)
		goto err_free_page;
	}

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

	cmd->mode = CMD_MODE_POLLING;
	cmd->allowed_opcode = CMD_ALLOWED_OPCODE_ALL;

	create_msg_cache(dev);

@@ -2013,3 +2057,10 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev)
	dma_pool_destroy(cmd->pool);
}
EXPORT_SYMBOL(mlx5_cmd_cleanup);

void mlx5_cmd_set_state(struct mlx5_core_dev *dev,
			enum mlx5_cmdif_state cmdif_state)
{
	dev->cmd.state = cmdif_state;
}
EXPORT_SYMBOL(mlx5_cmd_set_state);
+1 −1
Original line number Diff line number Diff line
@@ -1121,7 +1121,7 @@ void mlx5e_close_drop_rq(struct mlx5e_rq *drop_rq);
int mlx5e_create_indirect_rqt(struct mlx5e_priv *priv);

int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc);
void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc);
void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv);

int mlx5e_create_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs);
void mlx5e_destroy_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs);
+3 −2
Original line number Diff line number Diff line
@@ -699,6 +699,7 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
		       struct netlink_ext_ack *extack)
{
	struct mlx5_tc_ct_priv *ct_priv = mlx5_tc_ct_get_ct_priv(priv);
	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
	struct flow_dissector_key_ct *mask, *key;
	bool trk, est, untrk, unest, new;
	u32 ctstate = 0, ctstate_mask = 0;
@@ -706,7 +707,7 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
	u16 ct_state, ct_state_mask;
	struct flow_match_ct match;

	if (!flow_rule_match_key(f->rule, FLOW_DISSECTOR_KEY_CT))
	if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
		return 0;

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

	flow_rule_match_ct(f->rule, &match);
	flow_rule_match_ct(rule, &match);

	key = match.key;
	mask = match.mask;
+3 −1
Original line number Diff line number Diff line
@@ -130,7 +130,9 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
		       struct flow_cls_offload *f,
		       struct netlink_ext_ack *extack)
{
	if (!flow_rule_match_key(f->rule, FLOW_DISSECTOR_KEY_CT))
	struct flow_rule *rule = flow_cls_offload_flow_rule(f);

	if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
		return 0;

	NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
+1 −1
Original line number Diff line number Diff line
@@ -69,8 +69,8 @@ static void mlx5e_ktls_del(struct net_device *netdev,
	struct mlx5e_ktls_offload_context_tx *tx_priv =
		mlx5e_get_ktls_tx_priv_ctx(tls_ctx);

	mlx5_ktls_destroy_key(priv->mdev, tx_priv->key_id);
	mlx5e_destroy_tis(priv->mdev, tx_priv->tisn);
	mlx5_ktls_destroy_key(priv->mdev, tx_priv->key_id);
	kvfree(tx_priv);
}

Loading