From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA51DC433E0 for ; Wed, 20 May 2020 08:29:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 881B3207F9 for ; Wed, 20 May 2020 08:29:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1589963374; bh=vT0v4VkfJC357dWhGHBE8c0biiRKB8zMDVVzpRzfS2U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=WpziDxx7852u8N/WbVzgSEDFTn3M5j8iOc5MptumxvxiU6ZvXCYYMVGoL7VPQkcpv I2bHjGY8x0bOWt+SIPHp5+Dorgmr2gwJQFSpDSXGxGCd/afpkRMCcAn2AMPH7p24Ps jn6G5v6BNnPflpj+uUG6Aj/yG+lD0A/WjQH/RDTY= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726837AbgETI3d (ORCPT ); Wed, 20 May 2020 04:29:33 -0400 Received: from mail.kernel.org ([198.145.29.99]:49394 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726224AbgETI3d (ORCPT ); Wed, 20 May 2020 04:29:33 -0400 Received: from localhost (unknown [213.57.247.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 139D7206C3; Wed, 20 May 2020 08:29:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1589963372; bh=vT0v4VkfJC357dWhGHBE8c0biiRKB8zMDVVzpRzfS2U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ikLMW1zIJej4D8zXVr5azzGr8RbkCoyPMLzwDxdTRd/ODjySZi7+QtATOah1Hr5On rOy7NmhnhZQDX0JqoTIVleueAFKDOZEgY2NVRK130iYKYt/4h5MM1cawZ3FDVC5W+E w3fPXwvj6SceTAXbQbPX6oOwuC0LpdqzgBJJOCcA= From: Leon Romanovsky To: Doug Ledford , Jason Gunthorpe Cc: Leon Romanovsky , linux-rdma@vger.kernel.org, Mark Zhang Subject: [PATCH rdma-next 3/8] RDMA/mlx5: Set ECE options during QP create Date: Wed, 20 May 2020 11:29:14 +0300 Message-Id: <20200520082919.440939-4-leon@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200520082919.440939-1-leon@kernel.org> References: <20200520082919.440939-1-leon@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org From: Leon Romanovsky 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 Signed-off-by: Leon Romanovsky --- 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