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

Merge tag 'mlx5-updates-2023-01-10' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

mlx5-updates-2023-01-10

1) From Gal: Add debugfs entries for netdev nic driver
   - ktls, flow steering and hairpin info
   - useful for debug and performance analysis
   - e.g hairpin queue attributes, dump ktls tx pool size, etc

2) From Maher: Update shared buffer configuration on PFC commands
   2.1) For every change of buffer's headroom, recalculate the size of shared
       buffer to be equal to "total_buffer_size" - "new_headroom_size".
       The new shared buffer size will be split in ratio of 3:1 between
       lossy and lossless pools, respectively.

   2.2) For each port buffer change, count the number of lossless buffers.
       If there is only one lossless buffer, then set its lossless pool
       usage threshold to be infinite. Otherwise, if there is more than
       one lossless buffer, set a usage threshold for each lossless buffer.

    While at it, add more verbosity to debug prints when handling user
    commands, to assist in future debug.

3) From Tariq: Throttle high rate FW commands

4) From Shay: Properly initialize management PF

5) Various cleanup patches
parents 76c3a449 96c31b5b
Loading
Loading
Loading
Loading
+71 −47
Original line number Diff line number Diff line
@@ -47,6 +47,25 @@
#define CREATE_TRACE_POINTS
#include "diag/cmd_tracepoint.h"

struct mlx5_ifc_mbox_out_bits {
	u8         status[0x8];
	u8         reserved_at_8[0x18];

	u8         syndrome[0x20];

	u8         reserved_at_40[0x40];
};

struct mlx5_ifc_mbox_in_bits {
	u8         opcode[0x10];
	u8         uid[0x10];

	u8         reserved_at_20[0x10];
	u8         op_mod[0x10];

	u8         reserved_at_40[0x40];
};

enum {
	CMD_IF_REV = 5,
};
@@ -70,6 +89,26 @@ enum {
	MLX5_CMD_DELIVERY_STAT_CMD_DESCR_ERR		= 0x10,
};

static u16 in_to_opcode(void *in)
{
	return MLX5_GET(mbox_in, in, opcode);
}

/* Returns true for opcodes that might be triggered very frequently and throttle
 * the command interface. Limit their command slots usage.
 */
static bool mlx5_cmd_is_throttle_opcode(u16 op)
{
	switch (op) {
	case MLX5_CMD_OP_CREATE_GENERAL_OBJECT:
	case MLX5_CMD_OP_DESTROY_GENERAL_OBJECT:
	case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
	case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
		return true;
	}
	return false;
}

static struct mlx5_cmd_work_ent *
cmd_alloc_ent(struct mlx5_cmd *cmd, struct mlx5_cmd_msg *in,
	      struct mlx5_cmd_msg *out, void *uout, int uout_size,
@@ -91,6 +130,7 @@ cmd_alloc_ent(struct mlx5_cmd *cmd, struct mlx5_cmd_msg *in,
	ent->context	= context;
	ent->cmd	= cmd;
	ent->page_queue = page_queue;
	ent->op         = in_to_opcode(in->first.data);
	refcount_set(&ent->refcnt, 1);

	return ent;
@@ -752,25 +792,6 @@ static int cmd_status_to_err(u8 status)
	}
}

struct mlx5_ifc_mbox_out_bits {
	u8         status[0x8];
	u8         reserved_at_8[0x18];

	u8         syndrome[0x20];

	u8         reserved_at_40[0x40];
};

struct mlx5_ifc_mbox_in_bits {
	u8         opcode[0x10];
	u8         uid[0x10];

	u8         reserved_at_20[0x10];
	u8         op_mod[0x10];

	u8         reserved_at_40[0x40];
};

void mlx5_cmd_out_err(struct mlx5_core_dev *dev, u16 opcode, u16 op_mod, void *out)
{
	u32 syndrome = MLX5_GET(mbox_out, out, syndrome);
@@ -788,7 +809,7 @@ static void cmd_status_print(struct mlx5_core_dev *dev, void *in, void *out)
	u16 opcode, op_mod;
	u16 uid;

	opcode = MLX5_GET(mbox_in, in, opcode);
	opcode = in_to_opcode(in);
	op_mod = MLX5_GET(mbox_in, in, op_mod);
	uid    = MLX5_GET(mbox_in, in, uid);

@@ -800,7 +821,7 @@ int mlx5_cmd_check(struct mlx5_core_dev *dev, int err, void *in, void *out)
{
	/* aborted due to PCI error or via reset flow mlx5_cmd_trigger_completions() */
	if (err == -ENXIO) {
		u16 opcode = MLX5_GET(mbox_in, in, opcode);
		u16 opcode = in_to_opcode(in);
		u32 syndrome;
		u8 status;

@@ -829,9 +850,9 @@ static void dump_command(struct mlx5_core_dev *dev,
			 struct mlx5_cmd_work_ent *ent, int input)
{
	struct mlx5_cmd_msg *msg = input ? ent->in : ent->out;
	u16 op = MLX5_GET(mbox_in, ent->lay->in, opcode);
	struct mlx5_cmd_mailbox *next = msg->next;
	int n = mlx5_calc_cmd_blocks(msg);
	u16 op = ent->op;
	int data_only;
	u32 offset = 0;
	int dump_len;
@@ -883,11 +904,6 @@ static void dump_command(struct mlx5_core_dev *dev,
	mlx5_core_dbg(dev, "cmd[%d]: end dump\n", ent->idx);
}

static u16 msg_to_opcode(struct mlx5_cmd_msg *in)
{
	return MLX5_GET(mbox_in, in->first.data, opcode);
}

static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced);

static void cb_timeout_handler(struct work_struct *work)
@@ -905,13 +921,13 @@ static void cb_timeout_handler(struct work_struct *work)
	/* Maybe got handled by eq recover ? */
	if (!test_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state)) {
		mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) Async, recovered after timeout\n", ent->idx,
			       mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
			       mlx5_command_str(ent->op), ent->op);
		goto out; /* phew, already handled */
	}

	ent->ret = -ETIMEDOUT;
	mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) Async, timeout. Will cause a leak of a command resource\n",
		       ent->idx, mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
		       ent->idx, mlx5_command_str(ent->op), ent->op);
	mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, true);

out:
@@ -985,7 +1001,6 @@ static void cmd_work_handler(struct work_struct *work)
	ent->lay = lay;
	memset(lay, 0, sizeof(*lay));
	memcpy(lay->in, ent->in->first.data, sizeof(lay->in));
	ent->op = be32_to_cpu(lay->in[0]) >> 16;
	if (ent->in->next)
		lay->in_ptr = cpu_to_be64(ent->in->next->dma);
	lay->inlen = cpu_to_be32(ent->in->len);
@@ -1098,12 +1113,12 @@ static void wait_func_handle_exec_timeout(struct mlx5_core_dev *dev,
	 */
	if (wait_for_completion_timeout(&ent->done, timeout)) {
		mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) recovered after timeout\n", ent->idx,
			       mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
			       mlx5_command_str(ent->op), ent->op);
		return;
	}

	mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) No done completion\n", ent->idx,
		       mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
		       mlx5_command_str(ent->op), ent->op);

	ent->ret = -ETIMEDOUT;
	mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, true);
@@ -1130,12 +1145,10 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)

	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));
			       mlx5_command_str(ent->op), ent->op);
	} 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_command_str(ent->op), ent->op);
	}
	mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n",
		      err, deliv_status_to_str(ent->status), ent->status);
@@ -1169,7 +1182,6 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
	u8 status = 0;
	int err = 0;
	s64 ds;
	u16 op;

	if (callback && page_queue)
		return -EINVAL;
@@ -1209,9 +1221,8 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
		goto out_free;

	ds = ent->ts2 - ent->ts1;
	op = MLX5_GET(mbox_in, in->first.data, opcode);
	if (op < MLX5_CMD_OP_MAX) {
		stats = &cmd->stats[op];
	if (ent->op < MLX5_CMD_OP_MAX) {
		stats = &cmd->stats[ent->op];
		spin_lock_irq(&stats->lock);
		stats->sum += ds;
		++stats->n;
@@ -1219,7 +1230,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
	}
	mlx5_core_dbg_mask(dev, 1 << MLX5_CMD_TIME,
			   "fw exec time for %s is %lld nsec\n",
			   mlx5_command_str(op), ds);
			   mlx5_command_str(ent->op), ds);

out_free:
	status = ent->status;
@@ -1816,7 +1827,7 @@ static struct mlx5_cmd_msg *alloc_msg(struct mlx5_core_dev *dev, int in_size,

static int is_manage_pages(void *in)
{
	return MLX5_GET(mbox_in, in, opcode) == MLX5_CMD_OP_MANAGE_PAGES;
	return in_to_opcode(in) == MLX5_CMD_OP_MANAGE_PAGES;
}

/*  Notes:
@@ -1827,8 +1838,9 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
		    int out_size, mlx5_cmd_cbk_t callback, void *context,
		    bool force_polling)
{
	u16 opcode = MLX5_GET(mbox_in, in, opcode);
	struct mlx5_cmd_msg *inb, *outb;
	u16 opcode = in_to_opcode(in);
	bool throttle_op;
	int pages_queue;
	gfp_t gfp;
	u8 token;
@@ -1837,13 +1849,21 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
	if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, opcode))
		return -ENXIO;

	throttle_op = mlx5_cmd_is_throttle_opcode(opcode);
	if (throttle_op) {
		/* atomic context may not sleep */
		if (callback)
			return -EINVAL;
		down(&dev->cmd.throttle_sem);
	}

	pages_queue = is_manage_pages(in);
	gfp = callback ? GFP_ATOMIC : GFP_KERNEL;

	inb = alloc_msg(dev, in_size, gfp);
	if (IS_ERR(inb)) {
		err = PTR_ERR(inb);
		return err;
		goto out_up;
	}

	token = alloc_token(&dev->cmd);
@@ -1877,6 +1897,9 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
	mlx5_free_cmd_msg(dev, outb);
out_in:
	free_msg(dev, inb);
out_up:
	if (throttle_op)
		up(&dev->cmd.throttle_sem);
	return err;
}

@@ -1950,8 +1973,8 @@ static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, u16 op
int mlx5_cmd_do(struct mlx5_core_dev *dev, void *in, int in_size, void *out, int out_size)
{
	int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, false);
	u16 opcode = MLX5_GET(mbox_in, in, opcode);
	u16 op_mod = MLX5_GET(mbox_in, in, op_mod);
	u16 opcode = in_to_opcode(in);

	return cmd_status_err(dev, err, opcode, op_mod, out);
}
@@ -1996,8 +2019,8 @@ int mlx5_cmd_exec_polling(struct mlx5_core_dev *dev, void *in, int in_size,
			  void *out, int out_size)
{
	int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, true);
	u16 opcode = MLX5_GET(mbox_in, in, opcode);
	u16 op_mod = MLX5_GET(mbox_in, in, op_mod);
	u16 opcode = in_to_opcode(in);

	err = cmd_status_err(dev, err, opcode, op_mod, out);
	return mlx5_cmd_check(dev, err, in, out);
@@ -2049,7 +2072,7 @@ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,

	work->ctx = ctx;
	work->user_callback = callback;
	work->opcode = MLX5_GET(mbox_in, in, opcode);
	work->opcode = in_to_opcode(in);
	work->op_mod = MLX5_GET(mbox_in, in, op_mod);
	work->out = out;
	if (WARN_ON(!atomic_inc_not_zero(&ctx->num_inflight)))
@@ -2226,6 +2249,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)

	sema_init(&cmd->sem, cmd->max_reg_cmds);
	sema_init(&cmd->pages_sem, 1);
	sema_init(&cmd->throttle_sem, DIV_ROUND_UP(cmd->max_reg_cmds, 2));

	cmd_h = (u32)((u64)(cmd->dma) >> 32);
	cmd_l = (u32)(cmd->dma);
+6 −0
Original line number Diff line number Diff line
@@ -59,6 +59,9 @@ bool mlx5_eth_supported(struct mlx5_core_dev *dev)
	if (!IS_ENABLED(CONFIG_MLX5_CORE_EN))
		return false;

	if (mlx5_core_is_management_pf(dev))
		return false;

	if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
		return false;

@@ -198,6 +201,9 @@ bool mlx5_rdma_supported(struct mlx5_core_dev *dev)
	if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
		return false;

	if (mlx5_core_is_management_pf(dev))
		return false;

	if (dev->priv.flags & MLX5_PRIV_FLAGS_DISABLE_IB_ADEV)
		return false;

+8 −0
Original line number Diff line number Diff line
@@ -75,6 +75,10 @@ int mlx5_ec_init(struct mlx5_core_dev *dev)
	if (!mlx5_core_is_ecpf(dev))
		return 0;

	/* Management PF don't have a peer PF */
	if (mlx5_core_is_management_pf(dev))
		return 0;

	return mlx5_host_pf_init(dev);
}

@@ -85,6 +89,10 @@ void mlx5_ec_cleanup(struct mlx5_core_dev *dev)
	if (!mlx5_core_is_ecpf(dev))
		return;

	/* Management PF don't have a peer PF */
	if (mlx5_core_is_management_pf(dev))
		return;

	mlx5_host_pf_cleanup(dev);

	err = mlx5_wait_for_pages(dev, &dev->priv.host_pf_pages);
+2 −1
Original line number Diff line number Diff line
@@ -247,7 +247,7 @@ struct mlx5e_rx_wqe_ll {
};

struct mlx5e_rx_wqe_cyc {
	struct mlx5_wqe_data_seg      data[0];
	DECLARE_FLEX_ARRAY(struct mlx5_wqe_data_seg, data);
};

struct mlx5e_umr_wqe {
@@ -968,6 +968,7 @@ struct mlx5e_priv {
	struct mlx5e_scratchpad    scratchpad;
	struct mlx5e_htb          *htb;
	struct mlx5e_mqprio_rl    *mqprio_rl;
	struct dentry             *dfs_root;
};

struct mlx5e_rx_handlers {
+4 −1
Original line number Diff line number Diff line
@@ -145,7 +145,8 @@ void mlx5e_destroy_flow_steering(struct mlx5e_flow_steering *fs, bool ntuple,

struct mlx5e_flow_steering *mlx5e_fs_init(const struct mlx5e_profile *profile,
					  struct mlx5_core_dev *mdev,
					  bool state_destroy);
					  bool state_destroy,
					  struct dentry *dfs_root);
void mlx5e_fs_cleanup(struct mlx5e_flow_steering *fs);
struct mlx5e_vlan_table *mlx5e_fs_get_vlan(struct mlx5e_flow_steering *fs);
void mlx5e_fs_set_tc(struct mlx5e_flow_steering *fs, struct mlx5e_tc_table *tc);
@@ -189,6 +190,8 @@ int mlx5e_fs_vlan_rx_kill_vid(struct mlx5e_flow_steering *fs,
			      __be16 proto, u16 vid);
void mlx5e_fs_init_l2_addr(struct mlx5e_flow_steering *fs, struct net_device *netdev);

struct dentry *mlx5e_fs_get_debugfs_root(struct mlx5e_flow_steering *fs);

#define fs_err(fs, fmt, ...) \
	mlx5_core_err(mlx5e_fs_get_mdev(fs), fmt, ##__VA_ARGS__)

Loading