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: Ron Livne <ronli@voltaire.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
@@ -90,7 +90,8 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
|
|||||||
props->device_cap_flags = IB_DEVICE_CHANGE_PHY_PORT |
|
props->device_cap_flags = IB_DEVICE_CHANGE_PHY_PORT |
|
||||||
IB_DEVICE_PORT_ACTIVE_EVENT |
|
IB_DEVICE_PORT_ACTIVE_EVENT |
|
||||||
IB_DEVICE_SYS_IMAGE_GUID |
|
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)
|
if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR)
|
||||||
props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR;
|
props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR;
|
||||||
if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_QKEY_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)
|
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,
|
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)
|
static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
||||||
|
@@ -101,7 +101,8 @@ struct mlx4_ib_wq {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum mlx4_ib_qp_flags {
|
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 {
|
struct mlx4_ib_qp {
|
||||||
|
@@ -511,6 +511,9 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
|||||||
} else {
|
} else {
|
||||||
qp->sq_no_prefetch = 0;
|
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)
|
if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO)
|
||||||
qp->flags |= MLX4_IB_QP_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;
|
struct mlx4_ib_qp *qp;
|
||||||
int err;
|
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);
|
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))
|
(pd->uobject || init_attr->qp_type != IB_QPT_UD))
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
@@ -1844,6 +1852,13 @@ done:
|
|||||||
|
|
||||||
qp_init_attr->cap = qp_attr->cap;
|
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:
|
out:
|
||||||
mutex_unlock(&qp->mutex);
|
mutex_unlock(&qp->mutex);
|
||||||
return err;
|
return err;
|
||||||
|
@@ -38,6 +38,9 @@
|
|||||||
|
|
||||||
#include "mlx4.h"
|
#include "mlx4.h"
|
||||||
|
|
||||||
|
#define MGM_QPN_MASK 0x00FFFFFF
|
||||||
|
#define MGM_BLCK_LB_BIT 30
|
||||||
|
|
||||||
struct mlx4_mgm {
|
struct mlx4_mgm {
|
||||||
__be32 next_gid_index;
|
__be32 next_gid_index;
|
||||||
__be32 members_count;
|
__be32 members_count;
|
||||||
@@ -153,7 +156,8 @@ static int find_mgm(struct mlx4_dev *dev,
|
|||||||
return err;
|
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_priv *priv = mlx4_priv(dev);
|
||||||
struct mlx4_cmd_mailbox *mailbox;
|
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)
|
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);
|
mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn);
|
||||||
err = 0;
|
err = 0;
|
||||||
goto out;
|
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);
|
mgm->members_count = cpu_to_be32(members_count);
|
||||||
|
|
||||||
err = mlx4_WRITE_MCG(dev, index, mailbox);
|
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);
|
members_count = be32_to_cpu(mgm->members_count);
|
||||||
for (loc = -1, i = 0; i < members_count; ++i)
|
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;
|
loc = i;
|
||||||
|
|
||||||
if (loc == -1) {
|
if (loc == -1) {
|
||||||
|
@@ -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_INIT_PORT(struct mlx4_dev *dev, int port);
|
||||||
int mlx4_CLOSE_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_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,
|
int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list,
|
||||||
|
Reference in New Issue
Block a user