RDMA/mlx5: Perform check if QP creation flow is valid
Fast check that kernel and user flows provides enough data to create QP. Link: https://lore.kernel.org/r/20200427154636.381474-4-leon@kernel.org Reviewed-by: Maor Gottlieb <maorg@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
1265d9f7a5
commit
2242cc25ce
|
@ -1666,9 +1666,6 @@ static int create_rss_raw_qp_tir(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
|
||||||
size_t required_cmd_sz;
|
size_t required_cmd_sz;
|
||||||
u8 lb_flag = 0;
|
u8 lb_flag = 0;
|
||||||
|
|
||||||
if (init_attr->qp_type != IB_QPT_RAW_PACKET)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
if (init_attr->create_flags || init_attr->send_cq)
|
if (init_attr->create_flags || init_attr->send_cq)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -2032,13 +2029,8 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
|
||||||
if (mlx5_st < 0)
|
if (mlx5_st < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (init_attr->rwq_ind_tbl) {
|
if (init_attr->rwq_ind_tbl)
|
||||||
if (!udata)
|
return create_rss_raw_qp_tir(dev, qp, pd, init_attr, udata);
|
||||||
return -ENOSYS;
|
|
||||||
|
|
||||||
err = create_rss_raw_qp_tir(dev, qp, pd, init_attr, udata);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) {
|
if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) {
|
||||||
if (!MLX5_CAP_GEN(mdev, block_lb_mc)) {
|
if (!MLX5_CAP_GEN(mdev, block_lb_mc)) {
|
||||||
|
@ -2565,39 +2557,6 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
|
||||||
destroy_qp_user(dev, &get_pd(qp)->ibpd, qp, base, udata);
|
destroy_qp_user(dev, &get_pd(qp)->ibpd, qp, base, udata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *ib_qp_type_str(enum ib_qp_type type)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case IB_QPT_SMI:
|
|
||||||
return "IB_QPT_SMI";
|
|
||||||
case IB_QPT_GSI:
|
|
||||||
return "IB_QPT_GSI";
|
|
||||||
case IB_QPT_RC:
|
|
||||||
return "IB_QPT_RC";
|
|
||||||
case IB_QPT_UC:
|
|
||||||
return "IB_QPT_UC";
|
|
||||||
case IB_QPT_UD:
|
|
||||||
return "IB_QPT_UD";
|
|
||||||
case IB_QPT_RAW_IPV6:
|
|
||||||
return "IB_QPT_RAW_IPV6";
|
|
||||||
case IB_QPT_RAW_ETHERTYPE:
|
|
||||||
return "IB_QPT_RAW_ETHERTYPE";
|
|
||||||
case IB_QPT_XRC_INI:
|
|
||||||
return "IB_QPT_XRC_INI";
|
|
||||||
case IB_QPT_XRC_TGT:
|
|
||||||
return "IB_QPT_XRC_TGT";
|
|
||||||
case IB_QPT_RAW_PACKET:
|
|
||||||
return "IB_QPT_RAW_PACKET";
|
|
||||||
case MLX5_IB_QPT_REG_UMR:
|
|
||||||
return "MLX5_IB_QPT_REG_UMR";
|
|
||||||
case IB_QPT_DRIVER:
|
|
||||||
return "IB_QPT_DRIVER";
|
|
||||||
case IB_QPT_MAX:
|
|
||||||
default:
|
|
||||||
return "Invalid QP type";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ib_qp *mlx5_ib_create_dct(struct ib_pd *pd,
|
static struct ib_qp *mlx5_ib_create_dct(struct ib_pd *pd,
|
||||||
struct ib_qp_init_attr *attr,
|
struct ib_qp_init_attr *attr,
|
||||||
struct mlx5_ib_create_qp *ucmd,
|
struct mlx5_ib_create_qp *ucmd,
|
||||||
|
@ -2655,9 +2614,6 @@ static int set_mlx_qp_type(struct mlx5_ib_dev *dev,
|
||||||
enum { MLX_QP_FLAGS = MLX5_QP_FLAG_TYPE_DCT | MLX5_QP_FLAG_TYPE_DCI };
|
enum { MLX_QP_FLAGS = MLX5_QP_FLAG_TYPE_DCT | MLX5_QP_FLAG_TYPE_DCI };
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!udata)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (udata->inlen < sizeof(*ucmd)) {
|
if (udata->inlen < sizeof(*ucmd)) {
|
||||||
mlx5_ib_dbg(dev, "create_qp user command is smaller than expected\n");
|
mlx5_ib_dbg(dev, "create_qp user command is smaller than expected\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -2715,6 +2671,62 @@ out:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_valid_flow(struct mlx5_ib_dev *dev, struct ib_pd *pd,
|
||||||
|
struct ib_qp_init_attr *attr,
|
||||||
|
struct ib_udata *udata)
|
||||||
|
{
|
||||||
|
struct mlx5_ib_ucontext *ucontext = rdma_udata_to_drv_context(
|
||||||
|
udata, struct mlx5_ib_ucontext, ibucontext);
|
||||||
|
|
||||||
|
if (!udata) {
|
||||||
|
/* Kernel create_qp callers */
|
||||||
|
if (attr->rwq_ind_tbl)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
switch (attr->qp_type) {
|
||||||
|
case IB_QPT_RAW_PACKET:
|
||||||
|
case IB_QPT_DRIVER:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Userspace create_qp callers */
|
||||||
|
if (attr->qp_type == IB_QPT_RAW_PACKET && !ucontext->cqe_version) {
|
||||||
|
mlx5_ib_dbg(dev,
|
||||||
|
"Raw Packet QP is only supported for CQE version > 0\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr->qp_type != IB_QPT_RAW_PACKET && attr->rwq_ind_tbl) {
|
||||||
|
mlx5_ib_dbg(dev,
|
||||||
|
"Wrong QP type %d for the RWQ indirect table\n",
|
||||||
|
attr->qp_type);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (attr->qp_type) {
|
||||||
|
case IB_QPT_SMI:
|
||||||
|
case MLX5_IB_QPT_HW_GSI:
|
||||||
|
case MLX5_IB_QPT_REG_UMR:
|
||||||
|
case IB_QPT_GSI:
|
||||||
|
mlx5_ib_dbg(dev, "Kernel doesn't support QP type %d\n",
|
||||||
|
attr->qp_type);
|
||||||
|
return -EINVAL;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't need to see this warning, it means that kernel code
|
||||||
|
* missing ib_pd. Placed here to catch developer's mistakes.
|
||||||
|
*/
|
||||||
|
WARN_ONCE(!pd && attr->qp_type != IB_QPT_XRC_TGT,
|
||||||
|
"There is a missing PD pointer assignment\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
|
struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
|
||||||
struct ib_qp_init_attr *verbs_init_attr,
|
struct ib_qp_init_attr *verbs_init_attr,
|
||||||
struct ib_udata *udata)
|
struct ib_udata *udata)
|
||||||
|
@ -2725,8 +2737,6 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
|
||||||
int err;
|
int err;
|
||||||
struct ib_qp_init_attr mlx_init_attr;
|
struct ib_qp_init_attr mlx_init_attr;
|
||||||
struct ib_qp_init_attr *init_attr = verbs_init_attr;
|
struct ib_qp_init_attr *init_attr = verbs_init_attr;
|
||||||
struct mlx5_ib_ucontext *ucontext = rdma_udata_to_drv_context(
|
|
||||||
udata, struct mlx5_ib_ucontext, ibucontext);
|
|
||||||
|
|
||||||
dev = pd ? to_mdev(pd->device) :
|
dev = pd ? to_mdev(pd->device) :
|
||||||
to_mdev(to_mxrcd(init_attr->xrcd)->ibxrcd.device);
|
to_mdev(to_mxrcd(init_attr->xrcd)->ibxrcd.device);
|
||||||
|
@ -2738,25 +2748,9 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pd) {
|
err = check_valid_flow(dev, pd, init_attr, udata);
|
||||||
if (init_attr->qp_type == IB_QPT_RAW_PACKET) {
|
if (err)
|
||||||
if (!ucontext) {
|
return ERR_PTR(err);
|
||||||
mlx5_ib_dbg(dev, "Raw Packet QP is not supported for kernel consumers\n");
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
} else if (!ucontext->cqe_version) {
|
|
||||||
mlx5_ib_dbg(dev, "Raw Packet QP is only supported for CQE version > 0\n");
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* being cautious here */
|
|
||||||
if (init_attr->qp_type != IB_QPT_XRC_TGT &&
|
|
||||||
init_attr->qp_type != MLX5_IB_QPT_REG_UMR) {
|
|
||||||
pr_warn("%s: no PD for transport %s\n", __func__,
|
|
||||||
ib_qp_type_str(init_attr->qp_type));
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (init_attr->qp_type == IB_QPT_DRIVER) {
|
if (init_attr->qp_type == IB_QPT_DRIVER) {
|
||||||
struct mlx5_ib_create_qp ucmd;
|
struct mlx5_ib_create_qp ucmd;
|
||||||
|
|
Loading…
Reference in New Issue