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

Commit 521e575b authored by Ron Livne's avatar Ron Livne Committed by Roland Dreier
Browse files

IB/mlx4: Add support for blocking multicast loopback packets



Add support for handling the IB_QP_CREATE_MULTICAST_BLOCK_LOOPBACK
flag by using the per-multicast group loopback blocking feature of
mlx4 hardware.

Signed-off-by: default avatarRon Livne <ronli@voltaire.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 47ee1b9f
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -90,7 +90,8 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
	props->device_cap_flags    = IB_DEVICE_CHANGE_PHY_PORT |
		IB_DEVICE_PORT_ACTIVE_EVENT		|
		IB_DEVICE_SYS_IMAGE_GUID		|
		IB_DEVICE_RC_RNR_NAK_GEN;
		IB_DEVICE_RC_RNR_NAK_GEN		|
		IB_DEVICE_BLOCK_MULTICAST_LOOPBACK;
	if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR)
		props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR;
	if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_QKEY_CNTR)
@@ -437,7 +438,9 @@ static int mlx4_ib_dealloc_pd(struct ib_pd *pd)
static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
{
	return mlx4_multicast_attach(to_mdev(ibqp->device)->dev,
				     &to_mqp(ibqp)->mqp, gid->raw);
				     &to_mqp(ibqp)->mqp, gid->raw,
				     !!(to_mqp(ibqp)->flags &
					MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK));
}

static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
+2 −1
Original line number Diff line number Diff line
@@ -101,7 +101,8 @@ struct mlx4_ib_wq {
};

enum mlx4_ib_qp_flags {
	MLX4_IB_QP_LSO		= 1 << 0
	MLX4_IB_QP_LSO				= 1 << 0,
	MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK	= 1 << 1,
};

struct mlx4_ib_qp {
+18 −3
Original line number Diff line number Diff line
@@ -511,6 +511,9 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
	} else {
		qp->sq_no_prefetch = 0;

		if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)
			qp->flags |= MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK;

		if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO)
			qp->flags |= MLX4_IB_QP_LSO;

@@ -684,10 +687,15 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
	struct mlx4_ib_qp *qp;
	int err;

	/* We only support LSO, and only for kernel UD QPs. */
	if (init_attr->create_flags & ~IB_QP_CREATE_IPOIB_UD_LSO)
	/*
	 * We only support LSO and multicast loopback blocking, and
	 * only for kernel UD QPs.
	 */
	if (init_attr->create_flags & ~(IB_QP_CREATE_IPOIB_UD_LSO |
					IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK))
		return ERR_PTR(-EINVAL);
	if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO &&

	if (init_attr->create_flags &&
	    (pd->uobject || init_attr->qp_type != IB_QPT_UD))
		return ERR_PTR(-EINVAL);

@@ -1844,6 +1852,13 @@ int mlx4_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr

	qp_init_attr->cap	     = qp_attr->cap;

	qp_init_attr->create_flags = 0;
	if (qp->flags & MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK)
		qp_init_attr->create_flags |= IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK;

	if (qp->flags & MLX4_IB_QP_LSO)
		qp_init_attr->create_flags |= IB_QP_CREATE_IPOIB_UD_LSO;

out:
	mutex_unlock(&qp->mutex);
	return err;
+13 −4
Original line number Diff line number Diff line
@@ -38,6 +38,9 @@

#include "mlx4.h"

#define MGM_QPN_MASK       0x00FFFFFF
#define MGM_BLCK_LB_BIT    30

struct mlx4_mgm {
	__be32			next_gid_index;
	__be32			members_count;
@@ -153,7 +156,8 @@ static int find_mgm(struct mlx4_dev *dev,
	return err;
}

int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
			  int block_mcast_loopback)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_cmd_mailbox *mailbox;
@@ -202,13 +206,18 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
	}

	for (i = 0; i < members_count; ++i)
		if (mgm->qp[i] == cpu_to_be32(qp->qpn)) {
		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
			mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn);
			err = 0;
			goto out;
		}

	mgm->qp[members_count++] = cpu_to_be32(qp->qpn);
	if (block_mcast_loopback)
		mgm->qp[members_count++] = cpu_to_be32((qp->qpn & MGM_QPN_MASK) |
						       (1 << MGM_BLCK_LB_BIT));
	else
		mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK);

	mgm->members_count       = cpu_to_be32(members_count);

	err = mlx4_WRITE_MCG(dev, index, mailbox);
@@ -283,7 +292,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])

	members_count = be32_to_cpu(mgm->members_count);
	for (loc = -1, i = 0; i < members_count; ++i)
		if (mgm->qp[i] == cpu_to_be32(qp->qpn))
		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn)
			loc = i;

	if (loc == -1) {
+2 −1
Original line number Diff line number Diff line
@@ -398,7 +398,8 @@ int mlx4_srq_query(struct mlx4_dev *dev, struct mlx4_srq *srq, int *limit_waterm
int mlx4_INIT_PORT(struct mlx4_dev *dev, int port);
int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port);

int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]);
int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
			  int block_mcast_loopback);
int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]);

int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list,