[ofa-general] [PATCH 2/3 v3] mlx4: enable discarding/passing multicast loopback packets by FW/HW.

Ron Livne ronli at voltaire.com
Thu Jun 26 07:34:46 PDT 2008


When attaching a QP to a multicast group, checks if mcast
loopback packets should be blocked (receives it as a parameter).
If so, it sets the mcast loopback block bit to 1.

When querying a QP (which is mlx4_ib_qp) using ib_qp_query,
the field create_flags of the struct ib_qp_init_attr that is given as
a parameter,  will now be set with the flags that were used when
this QP was created.


Signed-off-by: Ron Livne <ronli at voltaire.com>

Changes in v2:
IB_QP_BLOCK_LOOPBACK QP creation flag in version 1, is now called
IB_QP_CREATE_MULTICAST_BLOCK_LOOPBACK.

Changes in v3:
The if statement that decided whether to block multicast loopback packets
when attaching the QP, was replace with:
(to_mqp(ibqp)->flags & MLX4_IB_QP_BLOCK_LOOPBACK) ? 1 : 0);

Whitespaces deleted.



---
 linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/main.c    |    6 ++++--
 linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/mlx4_ib.h |    3 ++-
 linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/qp.c      |   15 ++++++++++++++-
 linux-2.6.26-rc2/drivers/net/mlx4/mcg.c               |   15 +++++++++++----
 linux-2.6.26-rc2/include/linux/mlx4/device.h          |    2 +-
 5 files changed, 32 insertions(+), 9 deletions(-)

Index: kernels/linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/main.c
===================================================================
--- kernels.orig/linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/main.c	2008-06-26 14:10:01.000000000 +0300
+++ kernels/linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/main.c	2008-06-26 14:10:19.000000000 +0300
@@ -90,7 +90,8 @@ static int mlx4_ib_query_device(struct i
 	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_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,8 @@ static int mlx4_ib_dealloc_pd(struct ib_
 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_LOOPBACK) ? 1 : 0);
 }

 static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
Index: kernels/linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/mlx4_ib.h
===================================================================
--- kernels.orig/linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/mlx4_ib.h	2008-06-26 14:10:01.000000000 +0300
+++ kernels/linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/mlx4_ib.h	2008-06-26 14:10:19.000000000 +0300
@@ -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_LOOPBACK       = 1 << 1,
 };

 struct mlx4_ib_qp {
Index: kernels/linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/qp.c
===================================================================
--- kernels.orig/linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/qp.c	2008-06-26 14:10:01.000000000 +0300
+++ kernels/linux-2.6.26-rc2/drivers/infiniband/hw/mlx4/qp.c	2008-06-26 14:10:19.000000000 +0300
@@ -506,6 +506,9 @@ static int create_qp_common(struct mlx4_
 	} else {
 		qp->sq_no_prefetch = 0;

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

@@ -680,7 +683,9 @@ struct ib_qp *mlx4_ib_create_qp(struct i
 	int err;

 	/* We only support LSO, and only for kernel UD QPs. */
-	if (init_attr->create_flags & ~IB_QP_CREATE_IPOIB_UD_LSO)
+	if (init_attr->create_flags &
+			~(IB_QP_CREATE_IPOIB_UD_LSO
+			| IB_QP_CREATE_MULTICAST_BLOCK_LOOPBACK))
 		return ERR_PTR(-EINVAL);
 	if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO &&
 	    (pd->uobject || init_attr->qp_type != IB_QPT_UD))
@@ -1862,6 +1867,14 @@ done:

 	qp_init_attr->cap	     = qp_attr->cap;

+	qp_init_attr->create_flags = 0;
+	if (qp->flags & MLX4_IB_QP_BLOCK_LOOPBACK)
+		qp_init_attr->create_flags
+			|= IB_QP_CREATE_MULTICAST_BLOCK_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;
Index: kernels/linux-2.6.26-rc2/drivers/net/mlx4/mcg.c
===================================================================
--- kernels.orig/linux-2.6.26-rc2/drivers/net/mlx4/mcg.c	2008-06-26 14:10:01.000000000 +0300
+++ kernels/linux-2.6.26-rc2/drivers/net/mlx4/mcg.c	2008-06-26 14:10:19.000000000 +0300
@@ -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,7 @@ 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_lb)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
 	struct mlx4_cmd_mailbox *mailbox;
@@ -202,13 +205,17 @@ int mlx4_multicast_attach(struct mlx4_de
 	}

 	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_lb)
+		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 +290,7 @@ int mlx4_multicast_detach(struct mlx4_de

 	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) {
Index: kernels/linux-2.6.26-rc2/include/linux/mlx4/device.h
===================================================================
--- kernels.orig/linux-2.6.26-rc2/include/linux/mlx4/device.h	2008-06-26 14:10:01.000000000 +0300
+++ kernels/linux-2.6.26-rc2/include/linux/mlx4/device.h	2008-06-26 14:10:19.000000000 +0300
@@ -398,7 +398,7 @@ int mlx4_srq_query(struct mlx4_dev *dev,
 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_lb);
 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,



More information about the general mailing list