Commit d72baceb authored by Tariq Toukan's avatar Tariq Toukan Committed by Saeed Mahameed
Browse files

net/mlx5e: Support per-mdev queue counter



Each queue counter object counts some events (in hardware) for the RQs
that are attached to it, like events of packet drops due to no receive
WQE (rx_out_of_buffer).

Each RQ can be attached to a queue counter only within the same vhca. To
still cover all RQs with these counters, we create multiple instances,
one per vhca.

The result that's shown to the user is now the sum of all instances.

Signed-off-by: default avatarTariq Toukan <tariqt@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent c73a3ab8
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -793,6 +793,7 @@ struct mlx5e_channel {
	DECLARE_BITMAP(state, MLX5E_CHANNEL_NUM_STATES);
	int                        ix;
	int                        vec_ix;
	int                        sd_ix;
	int                        cpu;
	/* Sync between icosq recovery and XSK enable/disable. */
	struct mutex               icosq_recovery_lock;
@@ -916,7 +917,7 @@ struct mlx5e_priv {
	bool                       tx_ptp_opened;
	bool                       rx_ptp_opened;
	struct hwtstamp_config     tstamp;
	u16                        q_counter;
	u16                        q_counter[MLX5_SD_MAX_GROUP_SZ];
	u16                        drop_rq_q_counter;
	struct notifier_block      events_nb;
	struct notifier_block      blocking_events_nb;
@@ -1031,12 +1032,12 @@ struct mlx5e_xsk_param;

struct mlx5e_rq_param;
int mlx5e_open_rq(struct mlx5e_params *params, struct mlx5e_rq_param *param,
		  struct mlx5e_xsk_param *xsk, int node,
		  struct mlx5e_xsk_param *xsk, int node, u16 q_counter,
		  struct mlx5e_rq *rq);
#define MLX5E_RQ_WQES_TIMEOUT 20000 /* msecs */
int mlx5e_wait_for_min_rx_wqes(struct mlx5e_rq *rq, int wait_time);
void mlx5e_close_rq(struct mlx5e_rq *rq);
int mlx5e_create_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param);
int mlx5e_create_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param, u16 q_counter);
void mlx5e_destroy_rq(struct mlx5e_rq *rq);

struct mlx5e_sq_param;
+33 −15
Original line number Diff line number Diff line
@@ -20,10 +20,8 @@
#define NUM_REQ_PPCNT_COUNTER_S1 MLX5_CMD_SET_MONITOR_NUM_PPCNT_COUNTER_SET1
#define NUM_REQ_Q_COUNTERS_S1    MLX5_CMD_SET_MONITOR_NUM_Q_COUNTERS_SET1

int mlx5e_monitor_counter_supported(struct mlx5e_priv *priv)
static int mlx5e_monitor_counter_cap(struct mlx5_core_dev *mdev)
{
	struct mlx5_core_dev *mdev = priv->mdev;

	if (!MLX5_CAP_GEN(mdev, max_num_of_monitor_counters))
		return false;
	if (MLX5_CAP_PCAM_REG(mdev, ppcnt) &&
@@ -36,24 +34,38 @@ int mlx5e_monitor_counter_supported(struct mlx5e_priv *priv)
	return true;
}

static void mlx5e_monitor_counter_arm(struct mlx5e_priv *priv)
int mlx5e_monitor_counter_supported(struct mlx5e_priv *priv)
{
	struct mlx5_core_dev *pos;
	int i;

	mlx5_sd_for_each_dev(i, priv->mdev, pos)
		if (!mlx5e_monitor_counter_cap(pos))
			return false;
	return true;
}

static void mlx5e_monitor_counter_arm(struct mlx5_core_dev *mdev)
{
	u32 in[MLX5_ST_SZ_DW(arm_monitor_counter_in)] = {};

	MLX5_SET(arm_monitor_counter_in, in, opcode,
		 MLX5_CMD_OP_ARM_MONITOR_COUNTER);
	mlx5_cmd_exec_in(priv->mdev, arm_monitor_counter, in);
	mlx5_cmd_exec_in(mdev, arm_monitor_counter, in);
}

static void mlx5e_monitor_counters_work(struct work_struct *work)
{
	struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
					       monitor_counters_work);
	struct mlx5_core_dev *pos;
	int i;

	mutex_lock(&priv->state_lock);
	mlx5e_stats_update_ndo_stats(priv);
	mutex_unlock(&priv->state_lock);
	mlx5e_monitor_counter_arm(priv);
	mlx5_sd_for_each_dev(i, priv->mdev, pos)
		mlx5e_monitor_counter_arm(pos);
}

static int mlx5e_monitor_event_handler(struct notifier_block *nb,
@@ -97,15 +109,13 @@ static int fill_monitor_counter_q_counter_set1(int cnt, int q_counter, u32 *in)
}

/* check if mlx5e_monitor_counter_supported before calling this function*/
static void mlx5e_set_monitor_counter(struct mlx5e_priv *priv)
static void mlx5e_set_monitor_counter(struct mlx5_core_dev *mdev, int q_counter)
{
	struct mlx5_core_dev *mdev = priv->mdev;
	int max_num_of_counters = MLX5_CAP_GEN(mdev, max_num_of_monitor_counters);
	int num_q_counters      = MLX5_CAP_GEN(mdev, num_q_monitor_counters);
	int num_ppcnt_counters  = !MLX5_CAP_PCAM_REG(mdev, ppcnt) ? 0 :
				  MLX5_CAP_GEN(mdev, num_ppcnt_monitor_counters);
	u32 in[MLX5_ST_SZ_DW(set_monitor_counter_in)] = {};
	int q_counter = priv->q_counter;
	int cnt	= 0;

	if (num_ppcnt_counters  >=  NUM_REQ_PPCNT_COUNTER_S1 &&
@@ -127,13 +137,17 @@ static void mlx5e_set_monitor_counter(struct mlx5e_priv *priv)
/* check if mlx5e_monitor_counter_supported before calling this function*/
void mlx5e_monitor_counter_init(struct mlx5e_priv *priv)
{
	struct mlx5_core_dev *pos;
	int i;

	INIT_WORK(&priv->monitor_counters_work, mlx5e_monitor_counters_work);
	MLX5_NB_INIT(&priv->monitor_counters_nb, mlx5e_monitor_event_handler,
		     MONITOR_COUNTER);
	mlx5_eq_notifier_register(priv->mdev, &priv->monitor_counters_nb);

	mlx5e_set_monitor_counter(priv);
	mlx5e_monitor_counter_arm(priv);
	mlx5_sd_for_each_dev(i, priv->mdev, pos) {
		mlx5_eq_notifier_register(pos, &priv->monitor_counters_nb);
		mlx5e_set_monitor_counter(pos, priv->q_counter[i]);
		mlx5e_monitor_counter_arm(pos);
	}
	queue_work(priv->wq, &priv->update_stats_work);
}

@@ -141,11 +155,15 @@ void mlx5e_monitor_counter_init(struct mlx5e_priv *priv)
void mlx5e_monitor_counter_cleanup(struct mlx5e_priv *priv)
{
	u32 in[MLX5_ST_SZ_DW(set_monitor_counter_in)] = {};
	struct mlx5_core_dev *pos;
	int i;

	MLX5_SET(set_monitor_counter_in, in, opcode,
		 MLX5_CMD_OP_SET_MONITOR_COUNTER);

	mlx5_cmd_exec_in(priv->mdev, set_monitor_counter, in);
	mlx5_eq_notifier_unregister(priv->mdev, &priv->monitor_counters_nb);
	mlx5_sd_for_each_dev(i, priv->mdev, pos) {
		mlx5_cmd_exec_in(pos, set_monitor_counter, in);
		mlx5_eq_notifier_unregister(pos, &priv->monitor_counters_nb);
	}
	cancel_work_sync(&priv->monitor_counters_work);
}
+1 −6
Original line number Diff line number Diff line
@@ -945,7 +945,6 @@ static u8 rq_end_pad_mode(struct mlx5_core_dev *mdev, struct mlx5e_params *param
int mlx5e_build_rq_param(struct mlx5_core_dev *mdev,
			 struct mlx5e_params *params,
			 struct mlx5e_xsk_param *xsk,
			 u16 q_counter,
			 struct mlx5e_rq_param *param)
{
	void *rqc = param->rqc;
@@ -1007,7 +1006,6 @@ int mlx5e_build_rq_param(struct mlx5_core_dev *mdev,
	MLX5_SET(wq, wq, log_wq_stride,
		 mlx5e_get_rqwq_log_stride(params->rq_wq_type, ndsegs));
	MLX5_SET(wq, wq, pd,               mdev->mlx5e_res.hw_objs.pdn);
	MLX5_SET(rqc, rqc, counter_set_id, q_counter);
	MLX5_SET(rqc, rqc, vsd,            params->vlan_strip_disable);
	MLX5_SET(rqc, rqc, scatter_fcs,    params->scatter_fcs_en);

@@ -1018,7 +1016,6 @@ int mlx5e_build_rq_param(struct mlx5_core_dev *mdev,
}

void mlx5e_build_drop_rq_param(struct mlx5_core_dev *mdev,
			       u16 q_counter,
			       struct mlx5e_rq_param *param)
{
	void *rqc = param->rqc;
@@ -1027,7 +1024,6 @@ void mlx5e_build_drop_rq_param(struct mlx5_core_dev *mdev,
	MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);
	MLX5_SET(wq, wq, log_wq_stride,
		 mlx5e_get_rqwq_log_stride(MLX5_WQ_TYPE_CYCLIC, 1));
	MLX5_SET(rqc, rqc, counter_set_id, q_counter);

	param->wq.buf_numa_node = dev_to_node(mlx5_core_dma_dev(mdev));
}
@@ -1292,13 +1288,12 @@ void mlx5e_build_xdpsq_param(struct mlx5_core_dev *mdev,

int mlx5e_build_channel_param(struct mlx5_core_dev *mdev,
			      struct mlx5e_params *params,
			      u16 q_counter,
			      struct mlx5e_channel_param *cparam)
{
	u8 icosq_log_wq_sz, async_icosq_log_wq_sz;
	int err;

	err = mlx5e_build_rq_param(mdev, params, NULL, q_counter, &cparam->rq);
	err = mlx5e_build_rq_param(mdev, params, NULL, &cparam->rq);
	if (err)
		return err;

+0 −3
Original line number Diff line number Diff line
@@ -130,10 +130,8 @@ void mlx5e_build_create_cq_param(struct mlx5e_create_cq_param *ccp, struct mlx5e
int mlx5e_build_rq_param(struct mlx5_core_dev *mdev,
			 struct mlx5e_params *params,
			 struct mlx5e_xsk_param *xsk,
			 u16 q_counter,
			 struct mlx5e_rq_param *param);
void mlx5e_build_drop_rq_param(struct mlx5_core_dev *mdev,
			       u16 q_counter,
			       struct mlx5e_rq_param *param);
void mlx5e_build_sq_param_common(struct mlx5_core_dev *mdev,
				 struct mlx5e_sq_param *param);
@@ -149,7 +147,6 @@ void mlx5e_build_xdpsq_param(struct mlx5_core_dev *mdev,
			     struct mlx5e_sq_param *param);
int mlx5e_build_channel_param(struct mlx5_core_dev *mdev,
			      struct mlx5e_params *params,
			      u16 q_counter,
			      struct mlx5e_channel_param *cparam);

u16 mlx5e_calc_sq_stop_room(struct mlx5_core_dev *mdev, struct mlx5e_params *params);
+7 −5
Original line number Diff line number Diff line
@@ -646,7 +646,6 @@ static void mlx5e_ptp_build_sq_param(struct mlx5_core_dev *mdev,

static void mlx5e_ptp_build_rq_param(struct mlx5_core_dev *mdev,
				     struct net_device *netdev,
				     u16 q_counter,
				     struct mlx5e_ptp_params *ptp_params)
{
	struct mlx5e_rq_param *rq_params = &ptp_params->rq_param;
@@ -655,7 +654,7 @@ static void mlx5e_ptp_build_rq_param(struct mlx5_core_dev *mdev,
	params->rq_wq_type = MLX5_WQ_TYPE_CYCLIC;
	mlx5e_init_rq_type_params(mdev, params);
	params->sw_mtu = netdev->max_mtu;
	mlx5e_build_rq_param(mdev, params, NULL, q_counter, rq_params);
	mlx5e_build_rq_param(mdev, params, NULL, rq_params);
}

static void mlx5e_ptp_build_params(struct mlx5e_ptp *c,
@@ -681,7 +680,7 @@ static void mlx5e_ptp_build_params(struct mlx5e_ptp *c,
	/* RQ */
	if (test_bit(MLX5E_PTP_STATE_RX, c->state)) {
		params->vlan_strip_disable = orig->vlan_strip_disable;
		mlx5e_ptp_build_rq_param(c->mdev, c->netdev, c->priv->q_counter, cparams);
		mlx5e_ptp_build_rq_param(c->mdev, c->netdev, cparams);
	}
}

@@ -714,13 +713,16 @@ static int mlx5e_ptp_open_rq(struct mlx5e_ptp *c, struct mlx5e_params *params,
			     struct mlx5e_rq_param *rq_param)
{
	int node = dev_to_node(c->mdev->device);
	int err;
	int err, sd_ix;
	u16 q_counter;

	err = mlx5e_init_ptp_rq(c, params, &c->rq);
	if (err)
		return err;

	return mlx5e_open_rq(params, rq_param, NULL, node, &c->rq);
	sd_ix = mlx5_sd_ch_ix_get_dev_ix(c->mdev, MLX5E_PTP_CHANNEL_IX);
	q_counter = c->priv->q_counter[sd_ix];
	return mlx5e_open_rq(params, rq_param, NULL, node, q_counter, &c->rq);
}

static int mlx5e_ptp_open_queues(struct mlx5e_ptp *c,
Loading