From: Leon Romanovsky <leon@kernel.org>
To: Doug Ledford <dledford@redhat.com>, Jason Gunthorpe <jgg@mellanox.com>
Cc: Leon Romanovsky <leonro@mellanox.com>,
linux-rdma@vger.kernel.org, Mark Zhang <markz@mellanox.com>
Subject: [PATCH rdma-next 3/8] RDMA/mlx5: Set ECE options during QP create
Date: Wed, 20 May 2020 11:29:14 +0300 [thread overview]
Message-ID: <20200520082919.440939-4-leon@kernel.org> (raw)
In-Reply-To: <20200520082919.440939-1-leon@kernel.org>
From: Leon Romanovsky <leonro@mellanox.com>
Allow users to ask creation of QPs with specific ECE options.
Such early set even before RDMA-CM connection is established
is useful if user knows exactly which option he needs.
Reviewed-by: Mark Zhang <markz@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
drivers/infiniband/hw/mlx5/qp.c | 73 ++++++++++++++++++++++++++++++---
include/uapi/rdma/mlx5-abi.h | 2 +
2 files changed, 69 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 74c1afeba5cb..25f3dd1871cd 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -1552,6 +1552,7 @@ struct mlx5_create_qp_params {
struct ib_udata *udata;
size_t inlen;
size_t outlen;
+ size_t ucmd_size;
void *ucmd;
u8 is_rss_raw : 1;
struct ib_qp_init_attr *attr;
@@ -1839,6 +1840,7 @@ static int get_atomic_mode(struct mlx5_ib_dev *dev,
static int create_xrc_tgt_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
struct mlx5_create_qp_params *params)
{
+ struct mlx5_ib_create_qp *ucmd = params->ucmd;
struct ib_qp_init_attr *attr = params->attr;
u32 uidx = params->uidx;
struct mlx5_ib_resources *devr = &dev->devr;
@@ -1860,6 +1862,8 @@ static int create_xrc_tgt_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
if (!in)
return -ENOMEM;
+ if (MLX5_CAP_GEN(mdev, ece_support))
+ MLX5_SET(create_qp_in, in, ece, ucmd->ece_options);
qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
MLX5_SET(qpc, qpc, st, MLX5_QP_ST_XRC);
@@ -1974,6 +1978,8 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
if (is_sqp(init_attr->qp_type))
qp->port = init_attr->port_num;
+ if (MLX5_CAP_GEN(mdev, ece_support))
+ MLX5_SET(create_qp_in, in, ece, ucmd->ece_options);
qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
MLX5_SET(qpc, qpc, st, mlx5_st);
@@ -2396,7 +2402,8 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
destroy_qp(dev, qp, base, udata);
}
-static int create_dct(struct ib_pd *pd, struct mlx5_ib_qp *qp,
+static int create_dct(struct mlx5_ib_dev *dev, struct ib_pd *pd,
+ struct mlx5_ib_qp *qp,
struct mlx5_create_qp_params *params)
{
struct ib_qp_init_attr *attr = params->attr;
@@ -2415,6 +2422,8 @@ static int create_dct(struct ib_pd *pd, struct mlx5_ib_qp *qp,
MLX5_SET(dctc, dctc, cqn, to_mcq(attr->recv_cq)->mcq.cqn);
MLX5_SET64(dctc, dctc, dc_access_key, ucmd->access_key);
MLX5_SET(dctc, dctc, user_index, uidx);
+ if (MLX5_CAP_GEN(dev->mdev, ece_support))
+ MLX5_SET(dctc, dctc, ece, ucmd->ece_options);
if (qp->flags_en & MLX5_QP_FLAG_SCATTER_CQE) {
int rcqe_sz = mlx5_ib_get_cqe_size(attr->recv_cq);
@@ -2715,13 +2724,22 @@ static int process_udata_size(struct mlx5_ib_dev *dev,
size_t inlen = udata->inlen;
params->outlen = min(outlen, sizeof(struct mlx5_ib_create_qp_resp));
+ params->ucmd_size = ucmd;
if (attr->qp_type == IB_QPT_DRIVER) {
- params->inlen = (inlen < ucmd) ? 0 : ucmd;
+ /* User has old rdma-core, which doesn't support ECE */
+ size_t min_inlen =
+ offsetof(struct mlx5_ib_create_qp, ece_options);
+
+ params->inlen = (inlen < min_inlen) ? 0 : min(inlen, ucmd);
goto out;
}
if (!params->is_rss_raw) {
- params->inlen = ucmd;
+ /*
+ * We will check in check_ucmd_data() that user
+ * cleared everything after inlen.
+ */
+ params->inlen = min(inlen, ucmd);
goto out;
}
@@ -2733,13 +2751,14 @@ static int process_udata_size(struct mlx5_ib_dev *dev,
return -EINVAL;
ucmd = sizeof(struct mlx5_ib_create_qp_rss);
+ params->ucmd_size = ucmd;
if (inlen > ucmd && !ib_is_udata_cleared(udata, ucmd, inlen - ucmd))
return -EINVAL;
params->inlen = min(ucmd, inlen);
out:
if (!params->inlen)
- mlx5_ib_dbg(dev, "udata is too small or not cleared\n");
+ mlx5_ib_dbg(dev, "udata is too small\n");
return (params->inlen) ? 0 : -EINVAL;
}
@@ -2756,7 +2775,7 @@ static int create_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
}
if (qp->type == MLX5_IB_QPT_DCT) {
- err = create_dct(pd, qp, params);
+ err = create_dct(dev, pd, qp, params);
goto out;
}
@@ -2855,6 +2874,44 @@ static int mlx5_ib_destroy_dct(struct mlx5_ib_qp *mqp)
return 0;
}
+static int check_ucmd_data(struct mlx5_ib_dev *dev,
+ struct mlx5_create_qp_params *params)
+{
+ struct ib_qp_init_attr *attr = params->attr;
+ struct ib_udata *udata = params->udata;
+ size_t size, last;
+ int ret;
+
+ if (params->is_rss_raw)
+ /*
+ * These QPs don't have "reserved" field in their
+ * create_qp input struct, so their data is always valid.
+ */
+ last = sizeof(struct mlx5_ib_create_qp_rss);
+ else
+ /* IB_QPT_RAW_PACKET doesn't have ECE data */
+ last = (attr->qp_type == IB_QPT_RAW_PACKET) ?
+ offsetof(struct mlx5_ib_create_qp, ece_options) :
+ offsetof(struct mlx5_ib_create_qp, reserved);
+
+ if (udata->inlen <= last)
+ /*
+ * User provides different create_qp structures based on the
+ * flow and we need to know if he cleared memory after our
+ * struct create_qp ends.
+ */
+ return 0;
+
+ size = udata->inlen - last;
+ ret = ib_is_udata_cleared(params->udata, last, size);
+ if (!ret)
+ mlx5_ib_dbg(
+ dev,
+ "udata is not cleared, inlen = %lu, ucmd = %lu, last = %lu, size = %lu\n",
+ udata->inlen, params->ucmd_size, last, size);
+ return ret ? 0 : -EINVAL;
+}
+
struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attr,
struct ib_udata *udata)
{
@@ -2888,7 +2945,11 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attr,
if (err)
return ERR_PTR(err);
- params.ucmd = kzalloc(params.inlen, GFP_KERNEL);
+ err = check_ucmd_data(dev, ¶ms);
+ if (err)
+ return ERR_PTR(err);
+
+ params.ucmd = kzalloc(params.ucmd_size, GFP_KERNEL);
if (!params.ucmd)
return ERR_PTR(-ENOMEM);
diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h
index 106fbb3bec6a..bc9d9e3cb369 100644
--- a/include/uapi/rdma/mlx5-abi.h
+++ b/include/uapi/rdma/mlx5-abi.h
@@ -322,6 +322,8 @@ struct mlx5_ib_create_qp {
__aligned_u64 sq_buf_addr;
__aligned_u64 access_key;
};
+ __u32 ece_options;
+ __u32 reserved;
};
/* RX Hash function flags */
--
2.26.2
next prev parent reply other threads:[~2020-05-20 8:29 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-20 8:29 [PATCH rdma-next 0/8] Driver part of the ECE Leon Romanovsky
2020-05-20 8:29 ` [PATCH mlx5-next 1/8] net/mlx5: Add ability to read and write ECE options Leon Romanovsky
2020-05-20 8:29 ` [PATCH rdma-next 2/8] RDMA/mlx5: Get ECE options from FW during create QP Leon Romanovsky
2020-05-20 8:29 ` Leon Romanovsky [this message]
2020-05-20 8:29 ` [PATCH rdma-next 4/8] RDMA/mlx5: Use direct modify QP implementation Leon Romanovsky
2020-05-20 8:29 ` [PATCH rdma-next 5/8] RDMA/mlx5: Remove manually crafted QP context the query call Leon Romanovsky
2020-05-20 8:29 ` [PATCH rdma-next 6/8] RDMA/mlx5: Convert modify QP to use MLX5_SET macros Leon Romanovsky
2020-05-20 8:29 ` [PATCH rdma-next 7/8] RDMA/mlx5: Set ECE options during modify QP Leon Romanovsky
2020-05-20 8:29 ` [PATCH rdma-next 8/8] RDMA/mlx5: Return ECE data after " Leon Romanovsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200520082919.440939-4-leon@kernel.org \
--to=leon@kernel.org \
--cc=dledford@redhat.com \
--cc=jgg@mellanox.com \
--cc=leonro@mellanox.com \
--cc=linux-rdma@vger.kernel.org \
--cc=markz@mellanox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.