From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id DBA4DA034F; Sat, 16 Oct 2021 11:12:53 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 27CB741152; Sat, 16 Oct 2021 11:12:47 +0200 (CEST) Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1anam02on2069.outbound.protection.outlook.com [40.107.96.69]) by mails.dpdk.org (Postfix) with ESMTP id 6D6E54003F for ; Sat, 16 Oct 2021 11:12:43 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TzMkQeB7DgUbW+w2qKRUp70b3lqjChNqhQKaaWroXXuTvolYGx49Yceh0XTyEIuOB84nth9Wms6EIFUuRIZdgryoO8iJuK3slUfdWvMW7hFwv8TwOVNwQmH+0AyPm2agj7Ay6j+QfJBNP138mdEK2N8C3OF8omzrYfoctNmXxyW+z+jzgmZComVXmqMf+VrXZvvzLQ6XdorzhIapXWnf8m7CvYZG3a3pSpS/V+qgjUW0eZXjGwI4b70EmvdxcLlt6MzBaSrrIXcd0dIalpzez13IiE2e0fd6lXfqQKhO58680vYmnOscYdIO7NUB+xK0w5amQcVxOEOQujSGRvRbBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=u64ib6fvXtqt9ufhfthk3nXayYhR6l1ORM3NR1xFqF4=; b=P18Gnmdjo+4oVlMP3rGdo8JzTqXd0T4NPD3+ToWv9lESpL/9q4uXkCH8DU8PRzr6fzBEfl0Oj0ZTiBQD1+EmCXtjoW5U9eiJOvRSkx1mbmHrsD+3zt5nZxi85QQ4MogF0GACGApqsljljvUaWTM2jG5PxNgiuofoADJFalnjOX6rzpzP8jvCs8YrhEAp0BkLxXm0H9MVZfv69JR5jIyd/i60TKcx77+R88Nchz9ZVpPVAU/OTMBqbWQxGlt5rqy2JNHHaJ0B96IkF4o8WbE8gnffLgKn+L9HYpnrCQtOHrnEgUjjoRr7v7qUBAtoZE1koRlXENm1tqpYwznRsgRFpQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=ashroe.eu smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=u64ib6fvXtqt9ufhfthk3nXayYhR6l1ORM3NR1xFqF4=; b=oRy/b9tIl6rZ7LNWdz9Mjg5rie1eKsI4T7qtcxKblN3O1RBPZQeNvwZlEjU9trNL/zW6iD36L7KzUtYZHxNRbcaGKcsY3DMrQQI9A/kCpZ3ebKPJwXGIlIYDX7kMurRMfA1FIomNd7dHsCBH7+Ao2V5uKE0MonvXRqTqJnCHjc2ADiYTxW+ks54bEw5Nq0PM2MXseyusDSp6u9Btv4w9YrSDU2qodwarxmMyGFJ6kIHZlBGdoPwh8Ay8j3w9Z8d1nhQTiB5pC3qQg5EdXxZwoSE9FNL5cbpXPy2StMneOvjI2nGbYFribwuxginAne1+CSex/cKGr+cqv6IX6H6TCw== Received: from BN0PR03CA0003.namprd03.prod.outlook.com (2603:10b6:408:e6::8) by CO6PR12MB5443.namprd12.prod.outlook.com (2603:10b6:303:13a::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.16; Sat, 16 Oct 2021 09:12:40 +0000 Received: from BN8NAM11FT009.eop-nam11.prod.protection.outlook.com (2603:10b6:408:e6:cafe::3e) by BN0PR03CA0003.outlook.office365.com (2603:10b6:408:e6::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.15 via Frontend Transport; Sat, 16 Oct 2021 09:12:39 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; ashroe.eu; dkim=none (message not signed) header.d=none;ashroe.eu; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by BN8NAM11FT009.mail.protection.outlook.com (10.13.176.65) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4608.15 via Frontend Transport; Sat, 16 Oct 2021 09:12:39 +0000 Received: from nvidia.com (172.20.187.5) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Sat, 16 Oct 2021 09:12:36 +0000 From: Xueming Li To: CC: , Lior Margalit , Matan Azrad , Viacheslav Ovsiienko , "Ray Kinsella" Date: Sat, 16 Oct 2021 17:12:02 +0800 Message-ID: <20211016091214.1831902-3-xuemingl@nvidia.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211016091214.1831902-1-xuemingl@nvidia.com> References: <20210926111904.237736-1-xuemingl@nvidia.com> <20211016091214.1831902-1-xuemingl@nvidia.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [172.20.187.5] X-ClientProxiedBy: HQMAIL111.nvidia.com (172.20.187.18) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ff1d43e1-89d3-47d3-6f83-08d990851a3f X-MS-TrafficTypeDiagnostic: CO6PR12MB5443: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:2331; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: QI8gKawbvq+DwZmzZ0AaoHZb9sgkCMh9gnxgRZ/tyOYTzCE2NtFVqpoZq5mE5I3w+mx7H31k1Y4Uffrwc1aJdkQmempR5IeQ4/TKEAreQNcupeYOZ1+0/+/hbiDK5tLMC0LovA0wUbuzNqEUGPMQx0PChkUu5eg5ztE9w2pDDTbz5FLQAChSdU9ZXkaApFzNxCtBGnzyphzFdvAgZmo6OMerxjZCvMn4xz4oJWAzht95HUl982g5+UTs6HihUvlmL2pRxh4g9zSBoZcJOETGeMqflUOc2Pi1/fhOpdZHur/7kh6NIUyviynZlcgIZ2veDodjD3+qp3M8nLTSVEiTjIR8JZpw1LTcRuyXHMLKLx89TrXJ0SHlgSCmJBYzdys9agKPDQ5/WSYuZhZbwsztFD8zzDXcxU6yi3JlwK/3/s0u+uwypnS9+fC0PbYG578SdmIl99wQ2Th2d8mH8Y45i0hYSK3+45oULSjpZJ51r9E2C7LjCILubC7EBTE+q2wreIYN01q7VhL6cbDMBmKg9cRGfJ4qwqOKGa/VuByDnZpJRFz5PNHgIz1ozQ2sNeTzxcYnvoE9L295ZwM8BeqGaECyFOD8LgkokeLY7jrzdaCvG/GDn4d6ZQKTa0IRwhLftPt1cDgW1oqHFABvJ1e++Coq0waM+PQldWJ0T5ctJLkSHu8c82WkkqeKWetOH/pSWmz033R9Uo1cyP+4qtE30g== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(36840700001)(46966006)(336012)(36756003)(26005)(316002)(36906005)(186003)(16526019)(55016002)(5660300002)(8676002)(6916009)(6666004)(426003)(7636003)(36860700001)(2616005)(8936002)(508600001)(2906002)(356005)(54906003)(4326008)(30864003)(83380400001)(47076005)(1076003)(70586007)(82310400003)(70206006)(7696005)(86362001)(6286002); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2021 09:12:39.3311 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ff1d43e1-89d3-47d3-6f83-08d990851a3f X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT009.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR12MB5443 Subject: [dpdk-dev] [PATCH v2 02/13] common/mlx5: support receive memory pool X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Adds DevX supports of PRM shared receive memory pool(RMP) object. RMP is used to support shared Rx queue. Multiple RQ could share same RMP. Memory buffers are supplied to RMP. This patch makes RMP RQ optional, created only if mlx5_devx_rq.rmp is set. Signed-off-by: Xueming Li --- drivers/common/mlx5/mlx5_common_devx.c | 296 +++++++++++++++++++++---- drivers/common/mlx5/mlx5_common_devx.h | 19 +- drivers/common/mlx5/mlx5_devx_cmds.c | 52 +++++ drivers/common/mlx5/mlx5_devx_cmds.h | 16 ++ drivers/common/mlx5/mlx5_prm.h | 85 ++++++- drivers/common/mlx5/version.map | 1 + drivers/net/mlx5/mlx5_devx.c | 4 +- 7 files changed, 425 insertions(+), 48 deletions(-) diff --git a/drivers/common/mlx5/mlx5_common_devx.c b/drivers/common/mlx5/mlx5_common_devx.c index 825f84b1833..db019418b39 100644 --- a/drivers/common/mlx5/mlx5_common_devx.c +++ b/drivers/common/mlx5/mlx5_common_devx.c @@ -271,6 +271,39 @@ mlx5_devx_sq_create(void *ctx, struct mlx5_devx_sq *sq_obj, uint16_t log_wqbb_n, return -rte_errno; } +/** + * Destroy DevX Receive Queue resources. + * + * @param[in] rq_res + * DevX RQ resource to destroy. + */ +static void +mlx5_devx_wq_res_destroy(struct mlx5_devx_wq_res *rq_res) +{ + if (rq_res->umem_obj) + claim_zero(mlx5_os_umem_dereg(rq_res->umem_obj)); + if (rq_res->umem_buf) + mlx5_free((void *)(uintptr_t)rq_res->umem_buf); + memset(rq_res, 0, sizeof(*rq_res)); +} + +/** + * Destroy DevX Receive Memory Pool. + * + * @param[in] rmp + * DevX RMP to destroy. + */ +static void +mlx5_devx_rmp_destroy(struct mlx5_devx_rmp *rmp) +{ + MLX5_ASSERT(rmp->ref_cnt == 0); + if (rmp->rmp) { + claim_zero(mlx5_devx_cmd_destroy(rmp->rmp)); + rmp->rmp = NULL; + } + mlx5_devx_wq_res_destroy(&rmp->wq); +} + /** * Destroy DevX Queue Pair. * @@ -389,55 +422,48 @@ mlx5_devx_qp_create(void *ctx, struct mlx5_devx_qp *qp_obj, uint16_t log_wqbb_n, void mlx5_devx_rq_destroy(struct mlx5_devx_rq *rq) { - if (rq->rq) + if (rq->rq) { claim_zero(mlx5_devx_cmd_destroy(rq->rq)); - if (rq->umem_obj) - claim_zero(mlx5_os_umem_dereg(rq->umem_obj)); - if (rq->umem_buf) - mlx5_free((void *)(uintptr_t)rq->umem_buf); + rq->rq = NULL; + if (rq->rmp) + rq->rmp->ref_cnt--; + } + if (rq->rmp == NULL) { + mlx5_devx_wq_res_destroy(&rq->wq); + } else { + if (rq->rmp->ref_cnt == 0) + mlx5_devx_rmp_destroy(rq->rmp); + } } /** - * Create Receive Queue using DevX API. - * - * Get a pointer to partially initialized attributes structure, and updates the - * following fields: - * wq_umem_valid - * wq_umem_id - * wq_umem_offset - * dbr_umem_valid - * dbr_umem_id - * dbr_addr - * log_wq_pg_sz - * All other fields are updated by caller. + * Create WQ resources using DevX API. * * @param[in] ctx * Context returned from mlx5 open_device() glue function. - * @param[in/out] rq_obj - * Pointer to RQ to create. * @param[in] wqe_size * Size of WQE structure. * @param[in] log_wqbb_n * Log of number of WQBBs in queue. - * @param[in] attr - * Pointer to RQ attributes structure. * @param[in] socket * Socket to use for allocation. + * @param[out] wq_attr + * Pointer to WQ attributes structure. + * @param[out] wq_res + * Pointer to WQ resource to create. * * @return * 0 on success, a negative errno value otherwise and rte_errno is set. */ -int -mlx5_devx_rq_create(void *ctx, struct mlx5_devx_rq *rq_obj, uint32_t wqe_size, - uint16_t log_wqbb_n, - struct mlx5_devx_create_rq_attr *attr, int socket) +static int +mlx5_devx_wq_init(void *ctx, uint32_t wqe_size, uint16_t log_wqbb_n, int socket, + struct mlx5_devx_wq_attr *wq_attr, + struct mlx5_devx_wq_res *wq_res) { - struct mlx5_devx_obj *rq = NULL; struct mlx5dv_devx_umem *umem_obj = NULL; void *umem_buf = NULL; size_t alignment = MLX5_WQE_BUF_ALIGNMENT; uint32_t umem_size, umem_dbrec; - uint16_t rq_size = 1 << log_wqbb_n; int ret; if (alignment == (size_t)-1) { @@ -446,7 +472,7 @@ mlx5_devx_rq_create(void *ctx, struct mlx5_devx_rq *rq_obj, uint32_t wqe_size, return -rte_errno; } /* Allocate memory buffer for WQEs and doorbell record. */ - umem_size = wqe_size * rq_size; + umem_size = wqe_size * (1 << log_wqbb_n); umem_dbrec = RTE_ALIGN(umem_size, MLX5_DBR_SIZE); umem_size += MLX5_DBR_SIZE; umem_buf = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, umem_size, @@ -464,14 +490,60 @@ mlx5_devx_rq_create(void *ctx, struct mlx5_devx_rq *rq_obj, uint32_t wqe_size, rte_errno = errno; goto error; } + /* Fill WQ attributes for RQ/RMP object creation. */ + wq_attr->wq_umem_valid = 1; + wq_attr->wq_umem_id = mlx5_os_get_umem_id(umem_obj); + wq_attr->wq_umem_offset = 0; + wq_attr->dbr_umem_valid = 1; + wq_attr->dbr_umem_id = wq_attr->wq_umem_id; + wq_attr->dbr_addr = umem_dbrec; + wq_attr->log_wq_pg_sz = MLX5_LOG_PAGE_SIZE; /* Fill attributes for RQ object creation. */ - attr->wq_attr.wq_umem_valid = 1; - attr->wq_attr.wq_umem_id = mlx5_os_get_umem_id(umem_obj); - attr->wq_attr.wq_umem_offset = 0; - attr->wq_attr.dbr_umem_valid = 1; - attr->wq_attr.dbr_umem_id = attr->wq_attr.wq_umem_id; - attr->wq_attr.dbr_addr = umem_dbrec; - attr->wq_attr.log_wq_pg_sz = MLX5_LOG_PAGE_SIZE; + wq_res->umem_buf = umem_buf; + wq_res->umem_obj = umem_obj; + wq_res->db_rec = RTE_PTR_ADD(umem_buf, umem_dbrec); + return 0; +error: + ret = rte_errno; + if (umem_obj) + claim_zero(mlx5_os_umem_dereg(umem_obj)); + if (umem_buf) + mlx5_free((void *)(uintptr_t)umem_buf); + rte_errno = ret; + return -rte_errno; +} + +/** + * Create standalone Receive Queue using DevX API. + * + * @param[in] ctx + * Context returned from mlx5 open_device() glue function. + * @param[in/out] rq_obj + * Pointer to RQ to create. + * @param[in] wqe_size + * Size of WQE structure. + * @param[in] log_wqbb_n + * Log of number of WQBBs in queue. + * @param[in] attr + * Pointer to RQ attributes structure. + * @param[in] socket + * Socket to use for allocation. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_devx_rq_std_create(void *ctx, struct mlx5_devx_rq *rq_obj, + uint32_t wqe_size, uint16_t log_wqbb_n, + struct mlx5_devx_create_rq_attr *attr, int socket) +{ + struct mlx5_devx_obj *rq; + int ret; + + ret = mlx5_devx_wq_init(ctx, wqe_size, log_wqbb_n, socket, + &attr->wq_attr, &rq_obj->wq); + if (ret != 0) + return ret; /* Create receive queue object with DevX. */ rq = mlx5_devx_cmd_create_rq(ctx, attr, socket); if (!rq) { @@ -479,21 +551,161 @@ mlx5_devx_rq_create(void *ctx, struct mlx5_devx_rq *rq_obj, uint32_t wqe_size, rte_errno = ENOMEM; goto error; } - rq_obj->umem_buf = umem_buf; - rq_obj->umem_obj = umem_obj; rq_obj->rq = rq; - rq_obj->db_rec = RTE_PTR_ADD(rq_obj->umem_buf, umem_dbrec); return 0; error: ret = rte_errno; - if (umem_obj) - claim_zero(mlx5_os_umem_dereg(umem_obj)); - if (umem_buf) - mlx5_free((void *)(uintptr_t)umem_buf); + mlx5_devx_wq_res_destroy(&rq_obj->wq); rte_errno = ret; return -rte_errno; } +/** + * Create Receive Memory Pool using DevX API. + * + * @param[in] ctx + * Context returned from mlx5 open_device() glue function. + * @param[in/out] rq_obj + * Pointer to RQ to create. + * @param[in] wqe_size + * Size of WQE structure. + * @param[in] log_wqbb_n + * Log of number of WQBBs in queue. + * @param[in] attr + * Pointer to RQ attributes structure. + * @param[in] socket + * Socket to use for allocation. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_devx_rmp_create(void *ctx, struct mlx5_devx_rmp *rmp_obj, + uint32_t wqe_size, uint16_t log_wqbb_n, + struct mlx5_devx_wq_attr *wq_attr, int socket) +{ + struct mlx5_devx_create_rmp_attr rmp_attr = { 0 }; + int ret; + + if (rmp_obj->rmp != NULL) + return 0; + rmp_attr.wq_attr = *wq_attr; + ret = mlx5_devx_wq_init(ctx, wqe_size, log_wqbb_n, socket, + &rmp_attr.wq_attr, &rmp_obj->wq); + if (ret != 0) + return ret; + rmp_attr.state = MLX5_RMPC_STATE_RDY; + rmp_attr.basic_cyclic_rcv_wqe = + wq_attr->wq_type == MLX5_WQ_TYPE_CYCLIC_STRIDING_RQ ? + 0 : 1; + /* Create receive queue object with DevX. */ + rmp_obj->rmp = mlx5_devx_cmd_create_rmp(ctx, &rmp_attr, socket); + if (rmp_obj->rmp == NULL) { + DRV_LOG(ERR, "Can't create DevX RMP object."); + rte_errno = ENOMEM; + goto error; + } + return 0; +error: + ret = rte_errno; + mlx5_devx_wq_res_destroy(&rmp_obj->wq); + rte_errno = ret; + return -rte_errno; +} + +/** + * Create Shared Receive Queue based on RMP using DevX API. + * + * @param[in] ctx + * Context returned from mlx5 open_device() glue function. + * @param[in/out] rq_obj + * Pointer to RQ to create. + * @param[in] wqe_size + * Size of WQE structure. + * @param[in] log_wqbb_n + * Log of number of WQBBs in queue. + * @param[in] attr + * Pointer to RQ attributes structure. + * @param[in] socket + * Socket to use for allocation. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_devx_rq_shared_create(void *ctx, struct mlx5_devx_rq *rq_obj, + uint32_t wqe_size, uint16_t log_wqbb_n, + struct mlx5_devx_create_rq_attr *attr, int socket) +{ + struct mlx5_devx_obj *rq; + int ret; + + ret = mlx5_devx_rmp_create(ctx, rq_obj->rmp, wqe_size, log_wqbb_n, + &attr->wq_attr, socket); + if (ret != 0) + return ret; + attr->mem_rq_type = MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_RMP; + attr->rmpn = rq_obj->rmp->rmp->id; + attr->flush_in_error_en = 0; + memset(&attr->wq_attr, 0, sizeof(attr->wq_attr)); + /* Create receive queue object with DevX. */ + rq = mlx5_devx_cmd_create_rq(ctx, attr, socket); + if (!rq) { + DRV_LOG(ERR, "Can't create DevX RMP RQ object."); + rte_errno = ENOMEM; + goto error; + } + rq_obj->rq = rq; + rq_obj->rmp->ref_cnt++; + return 0; +error: + ret = rte_errno; + mlx5_devx_rq_destroy(rq_obj); + rte_errno = ret; + return -rte_errno; +} + +/** + * Create Receive Queue using DevX API. Shared RQ is created only if rmp set. + * + * Get a pointer to partially initialized attributes structure, and updates the + * following fields: + * wq_umem_valid + * wq_umem_id + * wq_umem_offset + * dbr_umem_valid + * dbr_umem_id + * dbr_addr + * log_wq_pg_sz + * All other fields are updated by caller. + * + * @param[in] ctx + * Context returned from mlx5 open_device() glue function. + * @param[in/out] rq_obj + * Pointer to RQ to create. + * @param[in] wqe_size + * Size of WQE structure. + * @param[in] log_wqbb_n + * Log of number of WQBBs in queue. + * @param[in] attr + * Pointer to RQ attributes structure. + * @param[in] socket + * Socket to use for allocation. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_devx_rq_create(void *ctx, struct mlx5_devx_rq *rq_obj, + uint32_t wqe_size, uint16_t log_wqbb_n, + struct mlx5_devx_create_rq_attr *attr, int socket) +{ + if (rq_obj->rmp == NULL) + return mlx5_devx_rq_std_create(ctx, rq_obj, wqe_size, + log_wqbb_n, attr, socket); + return mlx5_devx_rq_shared_create(ctx, rq_obj, wqe_size, + log_wqbb_n, attr, socket); +} /** * Change QP state to RTS. diff --git a/drivers/common/mlx5/mlx5_common_devx.h b/drivers/common/mlx5/mlx5_common_devx.h index f699405f69b..b0d6e4a39e8 100644 --- a/drivers/common/mlx5/mlx5_common_devx.h +++ b/drivers/common/mlx5/mlx5_common_devx.h @@ -45,14 +45,27 @@ struct mlx5_devx_qp { volatile uint32_t *db_rec; /* The QP doorbell record. */ }; -/* DevX Receive Queue structure. */ -struct mlx5_devx_rq { - struct mlx5_devx_obj *rq; /* The RQ DevX object. */ +/* DevX Receive Queue resource structure. */ +struct mlx5_devx_wq_res { void *umem_obj; /* The RQ umem object. */ volatile void *umem_buf; volatile uint32_t *db_rec; /* The RQ doorbell record. */ }; +/* DevX Receive Queue structure. */ +struct mlx5_devx_rmp { + struct mlx5_devx_obj *rmp; /* The RMP DevX object. */ + uint32_t ref_cnt; /* Reference count. */ + struct mlx5_devx_wq_res wq; +}; + +/* DevX Receive Queue structure. */ +struct mlx5_devx_rq { + struct mlx5_devx_obj *rq; /* The RQ DevX object. */ + struct mlx5_devx_rmp *rmp; /* Shared RQ RMP object. */ + struct mlx5_devx_wq_res wq; /* WQ resource of standalone RQ. */ +}; + /* mlx5_common_devx.c */ __rte_internal diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index eefb869b7d8..8f6dae5c7f8 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -766,6 +766,8 @@ mlx5_devx_cmd_query_hca_attr(void *ctx, MLX5_GET(cmd_hca_cap, hcattr, flow_counter_bulk_alloc); attr->flow_counters_dump = MLX5_GET(cmd_hca_cap, hcattr, flow_counters_dump); + attr->log_max_rmp = MLX5_GET(cmd_hca_cap, hcattr, log_max_rmp); + attr->mem_rq_rmp = MLX5_GET(cmd_hca_cap, hcattr, mem_rq_rmp); attr->log_max_rqt_size = MLX5_GET(cmd_hca_cap, hcattr, log_max_rqt_size); attr->eswitch_manager = MLX5_GET(cmd_hca_cap, hcattr, eswitch_manager); @@ -1259,6 +1261,56 @@ mlx5_devx_cmd_modify_rq(struct mlx5_devx_obj *rq, } /** + * Create RMP using DevX API. + * + * @param[in] ctx + * Context returned from mlx5 open_device() glue function. + * @param [in] rmp_attr + * Pointer to create RMP attributes structure. + * @param [in] socket + * CPU socket ID for allocations. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_rmp(void *ctx, + struct mlx5_devx_create_rmp_attr *rmp_attr, + int socket) +{ + uint32_t in[MLX5_ST_SZ_DW(create_rmp_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_rmp_out)] = {0}; + void *rmp_ctx, *wq_ctx; + struct mlx5_devx_wq_attr *wq_attr; + struct mlx5_devx_obj *rmp = NULL; + + rmp = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*rmp), 0, socket); + if (!rmp) { + DRV_LOG(ERR, "Failed to allocate RMP data"); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(create_rmp_in, in, opcode, MLX5_CMD_OP_CREATE_RMP); + rmp_ctx = MLX5_ADDR_OF(create_rmp_in, in, ctx); + MLX5_SET(rmpc, rmp_ctx, state, rmp_attr->state); + MLX5_SET(rmpc, rmp_ctx, basic_cyclic_rcv_wqe, + rmp_attr->basic_cyclic_rcv_wqe); + wq_ctx = MLX5_ADDR_OF(rmpc, rmp_ctx, wq); + wq_attr = &rmp_attr->wq_attr; + devx_cmd_fill_wq_data(wq_ctx, wq_attr); + rmp->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, + sizeof(out)); + if (!rmp->obj) { + DRV_LOG(ERR, "Failed to create RMP using DevX"); + rte_errno = errno; + mlx5_free(rmp); + return NULL; + } + rmp->id = MLX5_GET(create_rmp_out, out, rmpn); + return rmp; +} + +/* * Create TIR using DevX API. * * @param[in] ctx diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index e149f8b4f57..5b2d4d4d8a4 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -101,6 +101,8 @@ struct mlx5_hca_flow_attr { struct mlx5_hca_attr { uint32_t eswitch_manager:1; uint32_t flow_counters_dump:1; + uint32_t mem_rq_rmp:1; + uint32_t log_max_rmp:5; uint32_t log_max_rqt_size:5; uint32_t parse_graph_flex_node:1; uint8_t flow_counter_bulk_alloc_bitmap; @@ -250,6 +252,17 @@ struct mlx5_devx_modify_rq_attr { uint32_t lwm:16; /* Contained WQ lwm. */ }; +/* Create RMP attributes structure, used by create RMP operation. */ +struct mlx5_devx_create_rmp_attr { + uint32_t rsvd0:8; + uint32_t state:4; + uint32_t rsvd1:20; + uint32_t basic_cyclic_rcv_wqe:1; + uint32_t rsvd4:31; + uint32_t rsvd8[10]; + struct mlx5_devx_wq_attr wq_attr; +}; + struct mlx5_rx_hash_field_select { uint32_t l3_prot_type:1; uint32_t l4_prot_type:1; @@ -527,6 +540,9 @@ __rte_internal int mlx5_devx_cmd_modify_rq(struct mlx5_devx_obj *rq, struct mlx5_devx_modify_rq_attr *rq_attr); __rte_internal +struct mlx5_devx_obj *mlx5_devx_cmd_create_rmp(void *ctx, + struct mlx5_devx_create_rmp_attr *rq_attr, int socket); +__rte_internal struct mlx5_devx_obj *mlx5_devx_cmd_create_tir(void *ctx, struct mlx5_devx_tir_attr *tir_attr); __rte_internal diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 5fd93958ac3..a267da42ba6 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -1061,6 +1061,10 @@ enum { MLX5_CMD_OP_CREATE_RQ = 0x908, MLX5_CMD_OP_MODIFY_RQ = 0x909, MLX5_CMD_OP_QUERY_RQ = 0x90b, + MLX5_CMD_OP_CREATE_RMP = 0x90c, + MLX5_CMD_OP_MODIFY_RMP = 0x90d, + MLX5_CMD_OP_DESTROY_RMP = 0x90e, + MLX5_CMD_OP_QUERY_RMP = 0x90f, MLX5_CMD_OP_CREATE_TIS = 0x912, MLX5_CMD_OP_QUERY_TIS = 0x915, MLX5_CMD_OP_CREATE_RQT = 0x916, @@ -1559,7 +1563,8 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 reserved_at_378[0x3]; u8 log_max_tis[0x5]; u8 basic_cyclic_rcv_wqe[0x1]; - u8 reserved_at_381[0x2]; + u8 reserved_at_381[0x1]; + u8 mem_rq_rmp[0x1]; u8 log_max_rmp[0x5]; u8 reserved_at_388[0x3]; u8 log_max_rqt[0x5]; @@ -2166,6 +2171,84 @@ struct mlx5_ifc_query_rq_in_bits { u8 reserved_at_60[0x20]; }; +enum { + MLX5_RMPC_STATE_RDY = 0x1, + MLX5_RMPC_STATE_ERR = 0x3, +}; + +struct mlx5_ifc_rmpc_bits { + u8 reserved_at_0[0x8]; + u8 state[0x4]; + u8 reserved_at_c[0x14]; + u8 basic_cyclic_rcv_wqe[0x1]; + u8 reserved_at_21[0x1f]; + u8 reserved_at_40[0x140]; + struct mlx5_ifc_wq_bits wq; +}; + +struct mlx5_ifc_query_rmp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0xc0]; + struct mlx5_ifc_rmpc_bits rmp_context; +}; + +struct mlx5_ifc_query_rmp_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 rmpn[0x18]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_modify_rmp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_rmp_bitmask_bits { + u8 reserved_at_0[0x20]; + u8 reserved_at_20[0x1f]; + u8 lwm[0x1]; +}; + +struct mlx5_ifc_modify_rmp_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 rmp_state[0x4]; + u8 reserved_at_44[0x4]; + u8 rmpn[0x18]; + u8 reserved_at_60[0x20]; + struct mlx5_ifc_rmp_bitmask_bits bitmask; + u8 reserved_at_c0[0x40]; + struct mlx5_ifc_rmpc_bits ctx; +}; + +struct mlx5_ifc_create_rmp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x8]; + u8 rmpn[0x18]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_create_rmp_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0xc0]; + struct mlx5_ifc_rmpc_bits ctx; +}; + struct mlx5_ifc_create_tis_out_bits { u8 status[0x8]; u8 reserved_at_8[0x18]; diff --git a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map index d3c5040aac8..eee05917aab 100644 --- a/drivers/common/mlx5/version.map +++ b/drivers/common/mlx5/version.map @@ -31,6 +31,7 @@ INTERNAL { mlx5_devx_cmd_create_geneve_tlv_option; mlx5_devx_cmd_create_import_kek_obj; mlx5_devx_cmd_create_qp; + mlx5_devx_cmd_create_rmp; mlx5_devx_cmd_create_rq; mlx5_devx_cmd_create_rqt; mlx5_devx_cmd_create_sq; diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c index 447d6bafb93..c65a6e5d4e7 100644 --- a/drivers/net/mlx5/mlx5_devx.c +++ b/drivers/net/mlx5/mlx5_devx.c @@ -514,8 +514,8 @@ mlx5_rxq_devx_obj_new(struct rte_eth_dev *dev, uint16_t idx) ret = mlx5_devx_modify_rq(tmpl, MLX5_RXQ_MOD_RST2RDY); if (ret) goto error; - rxq_data->wqes = (void *)(uintptr_t)tmpl->rq_obj.umem_buf; - rxq_data->rq_db = (uint32_t *)(uintptr_t)tmpl->rq_obj.db_rec; + rxq_data->wqes = (void *)(uintptr_t)tmpl->rq_obj.wq.umem_buf; + rxq_data->rq_db = (uint32_t *)(uintptr_t)tmpl->rq_obj.wq.db_rec; rxq_data->cq_arm_sn = 0; rxq_data->cq_ci = 0; mlx5_rxq_initialize(rxq_data); -- 2.33.0