Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13eab21f authored by Aviv Heller's avatar Aviv Heller Committed by Doug Ledford
Browse files

IB/mlx5: LAG QP load balancing



When LAG is active, QP tx affinity (the physical port
to which a QP is affined, or the TIS in case of raw-eth)
is set in a round robin fashion during state transition
from RESET to INIT.

Signed-off-by: default avatarAviv Heller <avivh@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 4babcf97
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -605,6 +605,7 @@ struct mlx5_roce {
	rwlock_t		netdev_lock;
	struct net_device	*netdev;
	struct notifier_block	nb;
	atomic_t		next_port;
};

struct mlx5_ib_dev {
+58 −5
Original line number Diff line number Diff line
@@ -1873,7 +1873,8 @@ static void get_cqs(enum ib_qp_type qp_type,
}

static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
				const struct mlx5_modify_raw_qp_param *raw_qp_param);
				const struct mlx5_modify_raw_qp_param *raw_qp_param,
				u8 lag_tx_affinity);

static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
{
@@ -1902,7 +1903,7 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
				.operation = MLX5_CMD_OP_2RST_QP
			};

			err = modify_raw_packet_qp(dev, qp, &raw_qp_param);
			err = modify_raw_packet_qp(dev, qp, &raw_qp_param, 0);
		}
		if (err)
			mlx5_ib_warn(dev, "mlx5_ib: modify QP 0x%06x to RESET failed\n",
@@ -2166,6 +2167,31 @@ static int modify_raw_packet_eth_prio(struct mlx5_core_dev *dev,
	return err;
}

static int modify_raw_packet_tx_affinity(struct mlx5_core_dev *dev,
					 struct mlx5_ib_sq *sq, u8 tx_affinity)
{
	void *in;
	void *tisc;
	int inlen;
	int err;

	inlen = MLX5_ST_SZ_BYTES(modify_tis_in);
	in = mlx5_vzalloc(inlen);
	if (!in)
		return -ENOMEM;

	MLX5_SET(modify_tis_in, in, bitmask.lag_tx_port_affinity, 1);

	tisc = MLX5_ADDR_OF(modify_tis_in, in, ctx);
	MLX5_SET(tisc, tisc, lag_tx_port_affinity, tx_affinity);

	err = mlx5_core_modify_tis(dev, sq->tisn, in, inlen);

	kvfree(in);

	return err;
}

static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
			 const struct ib_ah_attr *ah,
			 struct mlx5_qp_path *path, u8 port, int attr_mask,
@@ -2446,7 +2472,8 @@ static int modify_raw_packet_qp_sq(struct mlx5_core_dev *dev,
}

static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
				const struct mlx5_modify_raw_qp_param *raw_qp_param)
				const struct mlx5_modify_raw_qp_param *raw_qp_param,
				u8 tx_affinity)
{
	struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
	struct mlx5_ib_rq *rq = &raw_packet_qp->rq;
@@ -2487,8 +2514,16 @@ static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
			return err;
	}

	if (qp->sq.wqe_cnt)
	if (qp->sq.wqe_cnt) {
		if (tx_affinity) {
			err = modify_raw_packet_tx_affinity(dev->mdev, sq,
							    tx_affinity);
			if (err)
				return err;
		}

		return modify_raw_packet_qp_sq(dev->mdev, sq, sq_state);
	}

	return 0;
}
@@ -2547,6 +2582,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
	int mlx5_st;
	int err;
	u16 op;
	u8 tx_affinity = 0;

	context = kzalloc(sizeof(*context), GFP_KERNEL);
	if (!context)
@@ -2576,6 +2612,23 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
		}
	}

	if ((cur_state == IB_QPS_RESET) && (new_state == IB_QPS_INIT)) {
		if ((ibqp->qp_type == IB_QPT_RC) ||
		    (ibqp->qp_type == IB_QPT_UD &&
		     !(qp->flags & MLX5_IB_QP_SQPN_QP1)) ||
		    (ibqp->qp_type == IB_QPT_UC) ||
		    (ibqp->qp_type == IB_QPT_RAW_PACKET) ||
		    (ibqp->qp_type == IB_QPT_XRC_INI) ||
		    (ibqp->qp_type == IB_QPT_XRC_TGT)) {
			if (mlx5_lag_is_active(dev->mdev)) {
				tx_affinity = (unsigned int)atomic_add_return(1,
						&dev->roce.next_port) %
						MLX5_MAX_PORTS + 1;
				context->flags |= cpu_to_be32(tx_affinity << 24);
			}
		}
	}

	if (is_sqp(ibqp->qp_type)) {
		context->mtu_msgmax = (IB_MTU_256 << 5) | 8;
	} else if (ibqp->qp_type == IB_QPT_UD ||
@@ -2724,7 +2777,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
			raw_qp_param.rq_q_ctr_id = mibport->q_cnt_id;
			raw_qp_param.set_mask |= MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID;
		}
		err = modify_raw_packet_qp(dev, qp, &raw_qp_param);
		err = modify_raw_packet_qp(dev, qp, &raw_qp_param, tx_affinity);
	} else {
		err = mlx5_core_qp_modify(dev->mdev, op, optpar, context,
					  &base->mqp);