mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 19:56:18 +00:00
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:
parent
47ee1b9f2e
commit
521e575b9a
5 changed files with 40 additions and 11 deletions
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 @@ done:
|
|||
|
||||
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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue