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

net/mlx5e: Fix wrong max num channels indication



No XSK support in the enhanced IPoIB driver and representors.
Add a profile property to specify this, and enhance the logic
that calculates the max number of channels to take it into
account.

Fixes: db05815b ("net/mlx5e: Add XSK zero-copy support")
Signed-off-by: default avatarTariq Toukan <tariqt@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 7a32f296
Loading
Loading
Loading
Loading
+3 −9
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ do { \
enum mlx5e_rq_group {
	MLX5E_RQ_GROUP_REGULAR,
	MLX5E_RQ_GROUP_XSK,
	MLX5E_NUM_RQ_GROUPS /* Keep last. */
#define MLX5E_NUM_RQ_GROUPS(g) (1 + MLX5E_RQ_GROUP_##g)
};

static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size)
@@ -182,14 +182,6 @@ static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
		min_t(int, mlx5_comp_vectors_count(mdev), MLX5E_MAX_NUM_CHANNELS);
}

/* Use this function to get max num channels after netdev was created */
static inline int mlx5e_get_netdev_max_channels(struct net_device *netdev)
{
	return min_t(unsigned int,
		     netdev->num_rx_queues / MLX5E_NUM_RQ_GROUPS,
		     netdev->num_tx_queues);
}

struct mlx5e_tx_wqe {
	struct mlx5_wqe_ctrl_seg ctrl;
	struct mlx5_wqe_eth_seg  eth;
@@ -830,6 +822,7 @@ struct mlx5e_priv {
	struct net_device         *netdev;
	struct mlx5e_stats         stats;
	struct mlx5e_channel_stats channel_stats[MLX5E_MAX_NUM_CHANNELS];
	u16                        max_nch;
	u8                         max_opened_tc;
	struct hwtstamp_config     tstamp;
	u16                        q_counter;
@@ -871,6 +864,7 @@ struct mlx5e_profile {
		mlx5e_fp_handle_rx_cqe handle_rx_cqe_mpwqe;
	} rx_handlers;
	int	max_tc;
	u8	rq_groups;
};

void mlx5e_build_ptys2ethtool_map(void);
+3 −2
Original line number Diff line number Diff line
@@ -66,9 +66,10 @@ static inline void mlx5e_qid_get_ch_and_group(struct mlx5e_params *params,
	*group = qid / nch;
}

static inline bool mlx5e_qid_validate(struct mlx5e_params *params, u64 qid)
static inline bool mlx5e_qid_validate(const struct mlx5e_profile *profile,
				      struct mlx5e_params *params, u64 qid)
{
	return qid < params->num_channels * MLX5E_NUM_RQ_GROUPS;
	return qid < params->num_channels * profile->rq_groups;
}

/* Parameter calculations */
+1 −1
Original line number Diff line number Diff line
@@ -391,7 +391,7 @@ void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
{
	mutex_lock(&priv->state_lock);

	ch->max_combined   = mlx5e_get_netdev_max_channels(priv->netdev);
	ch->max_combined   = priv->max_nch;
	ch->combined_count = priv->channels.params.num_channels;
	if (priv->xsk.refcnt) {
		/* The upper half are XSK queues. */
+2 −1
Original line number Diff line number Diff line
@@ -611,7 +611,8 @@ static int validate_flow(struct mlx5e_priv *priv,
		return -ENOSPC;

	if (fs->ring_cookie != RX_CLS_FLOW_DISC)
		if (!mlx5e_qid_validate(&priv->channels.params, fs->ring_cookie))
		if (!mlx5e_qid_validate(priv->profile, &priv->channels.params,
					fs->ring_cookie))
			return -EINVAL;

	switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
+16 −20
Original line number Diff line number Diff line
@@ -1677,10 +1677,10 @@ static int mlx5e_open_sqs(struct mlx5e_channel *c,
			  struct mlx5e_channel_param *cparam)
{
	struct mlx5e_priv *priv = c->priv;
	int err, tc, max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
	int err, tc;

	for (tc = 0; tc < params->num_tc; tc++) {
		int txq_ix = c->ix + tc * max_nch;
		int txq_ix = c->ix + tc * priv->max_nch;

		err = mlx5e_open_txqsq(c, c->priv->tisn[tc], txq_ix,
				       params, &cparam->sq, &c->sq[tc], tc);
@@ -2438,11 +2438,10 @@ int mlx5e_create_indirect_rqt(struct mlx5e_priv *priv)

int mlx5e_create_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
{
	const int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
	int err;
	int ix;

	for (ix = 0; ix < max_nch; ix++) {
	for (ix = 0; ix < priv->max_nch; ix++) {
		err = mlx5e_create_rqt(priv, 1 /*size */, &tirs[ix].rqt);
		if (unlikely(err))
			goto err_destroy_rqts;
@@ -2460,10 +2459,9 @@ err_destroy_rqts:

void mlx5e_destroy_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
{
	const int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
	int i;

	for (i = 0; i < max_nch; i++)
	for (i = 0; i < priv->max_nch; i++)
		mlx5e_destroy_rqt(priv, &tirs[i].rqt);
}

@@ -2557,7 +2555,7 @@ static void mlx5e_redirect_rqts(struct mlx5e_priv *priv,
		mlx5e_redirect_rqt(priv, rqtn, MLX5E_INDIR_RQT_SIZE, rrp);
	}

	for (ix = 0; ix < mlx5e_get_netdev_max_channels(priv->netdev); ix++) {
	for (ix = 0; ix < priv->max_nch; ix++) {
		struct mlx5e_redirect_rqt_param direct_rrp = {
			.is_rss = false,
			{
@@ -2758,7 +2756,7 @@ static int mlx5e_modify_tirs_lro(struct mlx5e_priv *priv)
			goto free_in;
	}

	for (ix = 0; ix < mlx5e_get_netdev_max_channels(priv->netdev); ix++) {
	for (ix = 0; ix < priv->max_nch; ix++) {
		err = mlx5_core_modify_tir(mdev, priv->direct_tir[ix].tirn,
					   in, inlen);
		if (err)
@@ -2858,12 +2856,11 @@ static void mlx5e_netdev_set_tcs(struct net_device *netdev)

static void mlx5e_build_tc2txq_maps(struct mlx5e_priv *priv)
{
	int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
	int i, tc;

	for (i = 0; i < max_nch; i++)
	for (i = 0; i < priv->max_nch; i++)
		for (tc = 0; tc < priv->profile->max_tc; tc++)
			priv->channel_tc2txq[i][tc] = i + tc * max_nch;
			priv->channel_tc2txq[i][tc] = i + tc * priv->max_nch;
}

static void mlx5e_build_tx2sq_maps(struct mlx5e_priv *priv)
@@ -2884,7 +2881,7 @@ static void mlx5e_build_tx2sq_maps(struct mlx5e_priv *priv)
void mlx5e_activate_priv_channels(struct mlx5e_priv *priv)
{
	int num_txqs = priv->channels.num * priv->channels.params.num_tc;
	int num_rxqs = priv->channels.num * MLX5E_NUM_RQ_GROUPS;
	int num_rxqs = priv->channels.num * priv->profile->rq_groups;
	struct net_device *netdev = priv->netdev;

	mlx5e_netdev_set_tcs(netdev);
@@ -3306,7 +3303,6 @@ err_destroy_inner_tirs:

int mlx5e_create_direct_tirs(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
{
	const int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
	struct mlx5e_tir *tir;
	void *tirc;
	int inlen;
@@ -3319,7 +3315,7 @@ int mlx5e_create_direct_tirs(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
	if (!in)
		return -ENOMEM;

	for (ix = 0; ix < max_nch; ix++) {
	for (ix = 0; ix < priv->max_nch; ix++) {
		memset(in, 0, inlen);
		tir = &tirs[ix];
		tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
@@ -3358,10 +3354,9 @@ void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc)

void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
{
	const int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
	int i;

	for (i = 0; i < max_nch; i++)
	for (i = 0; i < priv->max_nch; i++)
		mlx5e_destroy_tir(priv->mdev, &tirs[i]);
}

@@ -3487,7 +3482,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s)
{
	int i;

	for (i = 0; i < mlx5e_get_netdev_max_channels(priv->netdev); i++) {
	for (i = 0; i < priv->max_nch; i++) {
		struct mlx5e_channel_stats *channel_stats = &priv->channel_stats[i];
		struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq;
		struct mlx5e_rq_stats *rq_stats = &channel_stats->rq;
@@ -4960,8 +4955,7 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
		return err;

	mlx5e_build_nic_params(mdev, &priv->xsk, rss, &priv->channels.params,
			       mlx5e_get_netdev_max_channels(netdev),
			       netdev->mtu);
			       priv->max_nch, netdev->mtu);

	mlx5e_timestamp_init(priv);

@@ -5164,6 +5158,7 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
	.rx_handlers.handle_rx_cqe       = mlx5e_handle_rx_cqe,
	.rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
	.max_tc		   = MLX5E_MAX_NUM_TC,
	.rq_groups	   = MLX5E_NUM_RQ_GROUPS(XSK),
};

/* mlx5e generic netdev management API (move to en_common.c) */
@@ -5181,6 +5176,7 @@ int mlx5e_netdev_init(struct net_device *netdev,
	priv->profile     = profile;
	priv->ppriv       = ppriv;
	priv->msglevel    = MLX5E_MSG_LEVEL;
	priv->max_nch     = netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1);
	priv->max_opened_tc = 1;

	mutex_init(&priv->state_lock);
@@ -5218,7 +5214,7 @@ struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,

	netdev = alloc_etherdev_mqs(sizeof(struct mlx5e_priv),
				    nch * profile->max_tc,
				    nch * MLX5E_NUM_RQ_GROUPS);
				    nch * profile->rq_groups);
	if (!netdev) {
		mlx5_core_err(mdev, "alloc_etherdev_mqs() failed\n");
		return NULL;
Loading