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 BD3E144119; Fri, 31 May 2024 05:51:49 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F071F40EDD; Fri, 31 May 2024 05:51:38 +0200 (CEST) Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12on2073.outbound.protection.outlook.com [40.107.244.73]) by mails.dpdk.org (Postfix) with ESMTP id 8F3834027C for ; Fri, 31 May 2024 05:51:18 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=JBoLG2F1H2XRNY0C+z6X8zPQrTAbKrhzTcj9KayuEHW48XE3vVcG0ImSb57MjFFMOdh21ct8vSAIuIXuydlhGKuAMYReqmzZWDXDwH/i/47w1sJDIB2577cKzcoBWFbMKRNK7qICJ4CFCt6dvyQwa2A4fj+sFAzCsfUckv2HM/Bp8nGw9sEEADr5y75U4GHQbg1MXOMhmbPVnzS7JhVYF5drLiHIjbhFXZ7egZSght9kp2eHeo8+SRSs7IoTc1ssQpsfq2XoVoR9Geexu8XX+sFLAshSn4D/oWwc0+Qt4JhOq4feV9dVqK5D38v2YbwuR94yDHl+8aZEfJMKMl2X0w== 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=gSXokyW16Elhqd8bgZY7/7Zo8PT9Az7cQes+Rzxy9bM=; b=mHsDDR9uAgDKsuK3Q7idy1IMz1H8xToZZSabansMPQJsWChDIC0Lbl3quH613uMMZ+L/qIwIqO64/azdp+mOASiXGQKo4ixwOnURYIBzB9fFozD6h1PUbXQSgLEhT+h5XPAOj8pkubUALJrRHO7rzFwpHo6Tsh+mhnqmq/sVbt/yVfBKzxCZ5pE5V+aQeP3selzcz0+3xZJUqY3oecN/54fKv5RuxtRGIw4LZAibVEOFKDpCZ9aLPXFbdxAB4NcyfhuF8AG7JIasvXXYNWV4Dxghu2qM+tIk4xDGl/Avwl3jY/nloR3fR6IPyZT5hWyFdC/Sys2EULVJX7ZvLMkukQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.160) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none (0) 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=gSXokyW16Elhqd8bgZY7/7Zo8PT9Az7cQes+Rzxy9bM=; b=ujCH1mi7Mk6+1bwl4XUF7CCbXPKsuYBd4waOaegpiJz9eLpqXCAfzQFi2ZD00uS2YzlkpwN7+4+t3yrIV8HzyL6IeULvXzzyiyLMHMX91yj305efZFGro39BZJ84NKw5zpWdFP8Q6T0lWtWQ8VuGzZK2Ol9jCIGVDC0vd2B1lfzykA60iqlgm/a6s0apHOFEWPqGIas4kjsvFaxaAxmvxtWwwyjIdjGMFtxbWs1L9QD31HIWUbvzyqMPb4fCXRhXQh8J4MtprqDfSTKQNjq6XAa8AN6joXPw0vhK5o0F2TWq0I5EP4C5fFQLMMIujFbnnveRW+JPJZ5ByUL6PKWftQ== Received: from BL1P222CA0007.NAMP222.PROD.OUTLOOK.COM (2603:10b6:208:2c7::12) by DS7PR12MB6262.namprd12.prod.outlook.com (2603:10b6:8:96::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7611.30; Fri, 31 May 2024 03:51:15 +0000 Received: from BL02EPF0001A107.namprd05.prod.outlook.com (2603:10b6:208:2c7:cafe::f2) by BL1P222CA0007.outlook.office365.com (2603:10b6:208:2c7::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7633.22 via Frontend Transport; Fri, 31 May 2024 03:51:15 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.160) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.117.160 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.160; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.160) by BL02EPF0001A107.mail.protection.outlook.com (10.167.241.136) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7633.15 via Frontend Transport; Fri, 31 May 2024 03:51:15 +0000 Received: from rnnvmail201.nvidia.com (10.129.68.8) by mail.nvidia.com (10.129.200.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Thu, 30 May 2024 20:51:02 -0700 Received: from nvidia.com (10.126.230.35) by rnnvmail201.nvidia.com (10.129.68.8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Thu, 30 May 2024 20:51:00 -0700 From: Suanming Mou To: Dariusz Sosnowski , Viacheslav Ovsiienko , Ori Kam , Matan Azrad CC: , Subject: [PATCH 3/3] net/mlx5: add external Tx queue map and unmap Date: Fri, 31 May 2024 11:50:34 +0800 Message-ID: <20240531035034.1731943-3-suanmingm@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240531035034.1731943-1-suanmingm@nvidia.com> References: <20240531035034.1731943-1-suanmingm@nvidia.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.126.230.35] X-ClientProxiedBy: rnnvmail201.nvidia.com (10.129.68.8) To rnnvmail201.nvidia.com (10.129.68.8) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL02EPF0001A107:EE_|DS7PR12MB6262:EE_ X-MS-Office365-Filtering-Correlation-Id: 00cb0684-8216-4dcd-93f9-08dc8124ebba X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230031|82310400017|36860700004|376005|1800799015; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?7yaUCogFh4yJc1JSGb/mMcqPZja1arNmuRyUgCH67APtftj0IbIZSnOxFDII?= =?us-ascii?Q?DDHXzsZb9mA1qiTx1eT/AZlTbo2EfvJdn93W8IOFnsWaYCrSgrOO+7S/Gd4F?= =?us-ascii?Q?3H0OaNNayEHTHCh4O4Db0KkKqt22oFIPttJ7uYHMF0VowvvmLCkkJK3x6Scc?= =?us-ascii?Q?7T4jMsSvgLBey/VwcOTLobw2NYJoTe6hReeP2o57ZEPEKlSE4OP7I7V5MntE?= =?us-ascii?Q?UcXrd1lzu4afs9b5IE6CG1HwGpv4XSsOdk3hqusDCHNNIYPg6MEXJ12ylaDi?= =?us-ascii?Q?wQl6BNp9f9I8BqKrvwF0KeKpLWl7MG67eqoZMnj4NA+semCAhybu4dnhu2Py?= =?us-ascii?Q?AyI9NQ42JVEBvbIr9CIcSgqH2UHgrxfhbJ4UBKgskGI6F+FQyOBRv7t5WkXX?= =?us-ascii?Q?oHW5Haw3XMj/KMx07TLC9V5JbV8B7UlDqJo5vomC1luiUIphgzYrtZ9c2XG1?= =?us-ascii?Q?Ukl6vqYXiooWN1NXwfA9ig03jxSLdKZrtrFsnbZpl4+wbK3S1lsWNjlLxg1C?= =?us-ascii?Q?GxnvM8RLOCNMMuMgJPXDT1QrsJHuCzXdITzagG2yIDUS6olEHCLm3s4mNR5c?= =?us-ascii?Q?1XXwjF/aDliTlKybFPmfHJjGFYyqMPI/NESyywHqKEu1Izy1s3Mkm/7XRgX+?= =?us-ascii?Q?uX5XxHyHoID/lJmwyBj0w2Z9WOb5z9u+IHccDiaR7hLl0xJ9YPIqxYaj5FNG?= =?us-ascii?Q?+yVZqG55C8lOKwue/4g1uKYRDoeBjh15px925pvA4XqqE5uhv7UQatkWj2C1?= =?us-ascii?Q?2uxvF0M7aql5D1uquKkAlHUkWJQFIc0CGdQ500OjcW8lrmTufUQ/bBkgE4AP?= =?us-ascii?Q?SFJxdawB4oURXpqEGQh60ovD/htMgv5TI27QCrYwe0P0iAVKoxv4Dv6gVaMQ?= =?us-ascii?Q?kKbNxdKQYS71ZD+iUo2I9q9VRiEtsE2lDYCONHm7oy0IrlEh/O4OyLHmFhi+?= =?us-ascii?Q?rxX+BDdANdepCkjZQYJbuPdRG5I9AIbg80Fs8h33dJj/5IWFGtEqN+9ghiBV?= =?us-ascii?Q?zL0+pWubdGGmJVceR3AiDYh4FDvNhJF6PT4og0GpT97YMWkWzOeORzzz27jm?= =?us-ascii?Q?TQRh/XumJ1DehLUjIhwuqzRoWj8qpVfrXArJNSLLAmTWfD/aCHKP1+nmOn7K?= =?us-ascii?Q?9KQ/74OJUQk1VL2O7sFW6BXBphrGW7iMeo8zaV7V35rQutiUjmjEsBs1z/1V?= =?us-ascii?Q?WwMCTSvnLTD2N3JMRAP3xnQxNy47BGxNM9RNnkmGm875Ra0buwEtQ6Zk0ii5?= =?us-ascii?Q?lFaX+hWtQ1p4SVpD17pM+G9tHd9Zs1rPnM7mMkEpuklZEp3xWftxmRrkoV+C?= =?us-ascii?Q?ZOEUBCa01FjyZ+d3E3AcEHTNqQHddVCMMofNuTACYq0vaoYO3HH3lFdXfY98?= =?us-ascii?Q?lA+54O8=3D?= X-Forefront-Antispam-Report: CIP:216.228.117.160; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:dc6edge1.nvidia.com; CAT:NONE; SFS:(13230031)(82310400017)(36860700004)(376005)(1800799015); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 May 2024 03:51:15.1415 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 00cb0684-8216-4dcd-93f9-08dc8124ebba X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.117.160]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BL02EPF0001A107.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS7PR12MB6262 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 For using external created Tx queues in RTE_FLOW_ITEM_TX_QUEUE, this commit provides the map and unmap functions to convert the external created SQ's devx ID to DPDK flow item Tx queue ID. Signed-off-by: Suanming Mou --- drivers/net/mlx5/linux/mlx5_os.c | 12 ++- drivers/net/mlx5/mlx5.c | 5 + drivers/net/mlx5/mlx5.h | 7 ++ drivers/net/mlx5/mlx5_defs.h | 3 + drivers/net/mlx5/mlx5_devx.c | 40 ++++++++ drivers/net/mlx5/mlx5_devx.h | 1 + drivers/net/mlx5/mlx5_ethdev.c | 8 ++ drivers/net/mlx5/mlx5_flow.h | 6 ++ drivers/net/mlx5/mlx5_rx.h | 6 -- drivers/net/mlx5/mlx5_rxq.c | 22 +---- drivers/net/mlx5/mlx5_tx.h | 25 +++++ drivers/net/mlx5/mlx5_txq.c | 152 +++++++++++++++++++++++++++++++ drivers/net/mlx5/rte_pmd_mlx5.h | 48 ++++++++++ drivers/net/mlx5/version.map | 3 + 14 files changed, 312 insertions(+), 26 deletions(-) diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c index 8cfbc25430..bb566ea236 100644 --- a/drivers/net/mlx5/linux/mlx5_os.c +++ b/drivers/net/mlx5/linux/mlx5_os.c @@ -1224,7 +1224,16 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, err = ENOMEM; goto error; } - DRV_LOG(DEBUG, "External RxQ is supported."); + priv->ext_txqs = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE, + sizeof(struct mlx5_external_q) * + MLX5_MAX_EXT_TX_QUEUES, 0, + SOCKET_ID_ANY); + if (priv->ext_txqs == NULL) { + DRV_LOG(ERR, "Fail to allocate external TxQ array."); + err = ENOMEM; + goto error; + } + DRV_LOG(DEBUG, "External queue is supported."); } priv->sh = sh; priv->dev_port = spawn->phys_port; @@ -1763,6 +1772,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, if (eth_dev && priv->flex_item_map) mlx5_flex_item_port_cleanup(eth_dev); mlx5_free(priv->ext_rxqs); + mlx5_free(priv->ext_txqs); mlx5_free(priv); if (eth_dev != NULL) eth_dev->data->dev_private = NULL; diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index d15302d00d..e41b1e82d7 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -2436,6 +2436,10 @@ mlx5_dev_close(struct rte_eth_dev *dev) if (ret) DRV_LOG(WARNING, "port %u some Verbs Tx queue still remain", dev->data->port_id); + ret = mlx5_ext_txq_verify(dev); + if (ret) + DRV_LOG(WARNING, "Port %u some external TxQ still remain.", + dev->data->port_id); ret = mlx5_txq_verify(dev); if (ret) DRV_LOG(WARNING, "port %u some Tx queues still remain", @@ -2447,6 +2451,7 @@ mlx5_dev_close(struct rte_eth_dev *dev) if (priv->hrxqs) mlx5_list_destroy(priv->hrxqs); mlx5_free(priv->ext_rxqs); + mlx5_free(priv->ext_txqs); sh->port[priv->dev_port - 1].nl_ih_port_id = RTE_MAX_ETHPORTS; /* * The interrupt handler port id must be reset before priv is reset diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 07d050b225..5b23043b8b 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -381,6 +381,12 @@ struct mlx5_lb_ctx { RTE_ATOMIC(uint16_t) refcnt; /* Reference count for representors. */ }; +/* External queue descriptor. */ +struct mlx5_external_q { + uint32_t hw_id; /* Queue index in the Hardware. */ + RTE_ATOMIC(uint32_t) refcnt; /* Reference counter. */ +}; + /* HW steering queue job descriptor type. */ enum mlx5_hw_job_type { MLX5_HW_Q_JOB_TYPE_CREATE, /* Flow create job type. */ @@ -1883,6 +1889,7 @@ struct mlx5_priv { unsigned int rxqs_n; /* RX queues array size. */ unsigned int txqs_n; /* TX queues array size. */ struct mlx5_external_q *ext_rxqs; /* External RX queues array. */ + struct mlx5_external_q *ext_txqs; /* External TX queues array. */ struct mlx5_rxq_priv *(*rxq_privs)[]; /* RX queue non-shared data. */ struct mlx5_txq_data *(*txqs)[]; /* TX queues. */ struct rte_mempool *mprq_mp; /* Mempool for Multi-Packet RQ. */ diff --git a/drivers/net/mlx5/mlx5_defs.h b/drivers/net/mlx5/mlx5_defs.h index dc5216cb24..9c454983be 100644 --- a/drivers/net/mlx5/mlx5_defs.h +++ b/drivers/net/mlx5/mlx5_defs.h @@ -183,6 +183,9 @@ /* Maximum number of external Rx queues supported by rte_flow */ #define MLX5_MAX_EXT_RX_QUEUES (UINT16_MAX - RTE_PMD_MLX5_EXTERNAL_RX_QUEUE_ID_MIN + 1) +/* Maximum number of external Tx queues supported by rte_flow */ +#define MLX5_MAX_EXT_TX_QUEUES (UINT16_MAX - MLX5_EXTERNAL_TX_QUEUE_ID_MIN + 1) + /* * Linux definition of static_assert is found in /usr/include/assert.h. * Windows does not require a redefinition. diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c index cae9d578ab..f23eb1def6 100644 --- a/drivers/net/mlx5/mlx5_devx.c +++ b/drivers/net/mlx5/mlx5_devx.c @@ -27,6 +27,46 @@ #include "mlx5_flow.h" #include "mlx5_flow_os.h" +/** + * Validate given external queue's port is valid or not. + * + * @param[in] port_id + * The port identifier of the Ethernet device. + * + * @return + * 0 on success, non-0 otherwise + */ +int +mlx5_devx_extq_port_validate(uint16_t port_id) +{ + struct rte_eth_dev *dev; + struct mlx5_priv *priv; + + if (rte_eth_dev_is_valid_port(port_id) < 0) { + DRV_LOG(ERR, "There is no Ethernet device for port %u.", + port_id); + rte_errno = ENODEV; + return -rte_errno; + } + dev = &rte_eth_devices[port_id]; + priv = dev->data->dev_private; + if (!mlx5_imported_pd_and_ctx(priv->sh->cdev)) { + DRV_LOG(ERR, "Port %u " + "external queue isn't supported on local PD and CTX.", + port_id); + rte_errno = ENOTSUP; + return -rte_errno; + } + if (!mlx5_devx_obj_ops_en(priv->sh)) { + DRV_LOG(ERR, + "Port %u external queue isn't supported by Verbs API.", + port_id); + rte_errno = ENOTSUP; + return -rte_errno; + } + return 0; +} + /** * Modify RQ vlan stripping offload * diff --git a/drivers/net/mlx5/mlx5_devx.h b/drivers/net/mlx5/mlx5_devx.h index ebd1da455a..4ab8cfbd22 100644 --- a/drivers/net/mlx5/mlx5_devx.h +++ b/drivers/net/mlx5/mlx5_devx.h @@ -12,6 +12,7 @@ int mlx5_txq_devx_modify(struct mlx5_txq_obj *obj, enum mlx5_txq_modify_type type, uint8_t dev_port); void mlx5_txq_devx_obj_release(struct mlx5_txq_obj *txq_obj); int mlx5_devx_modify_rq(struct mlx5_rxq_priv *rxq, uint8_t type); +int mlx5_devx_extq_port_validate(uint16_t port_id); extern struct mlx5_obj_ops devx_obj_ops; diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index aea799341c..1b721cda5e 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -123,6 +123,14 @@ mlx5_dev_configure(struct rte_eth_dev *dev) dev->data->port_id, priv->txqs_n, txqs_n); priv->txqs_n = txqs_n; } + if (priv->ext_txqs && txqs_n >= MLX5_EXTERNAL_TX_QUEUE_ID_MIN) { + DRV_LOG(ERR, "port %u cannot handle this many Tx queues (%u), " + "the maximal number of internal Tx queues is %u", + dev->data->port_id, txqs_n, + MLX5_EXTERNAL_TX_QUEUE_ID_MIN - 1); + rte_errno = EINVAL; + return -rte_errno; + } if (rxqs_n > priv->sh->dev_cap.ind_table_max_size) { DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)", dev->data->port_id, rxqs_n); diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 8f53e82985..9a359da042 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -1954,12 +1954,18 @@ static __rte_always_inline int flow_hw_get_sqn(struct rte_eth_dev *dev, uint16_t tx_queue, uint32_t *sqn) { struct mlx5_txq_ctrl *txq; + struct mlx5_external_q *ext_txq; /* Means Tx queue is PF0. */ if (tx_queue == UINT16_MAX) { *sqn = 0; return 0; } + if (mlx5_is_external_txq(dev, tx_queue)) { + ext_txq = mlx5_ext_txq_get(dev, tx_queue); + *sqn = ext_txq->hw_id; + return 0; + } txq = mlx5_txq_get(dev, tx_queue); if (unlikely(!txq)) return -ENOENT; diff --git a/drivers/net/mlx5/mlx5_rx.h b/drivers/net/mlx5/mlx5_rx.h index decb14e708..1485556d89 100644 --- a/drivers/net/mlx5/mlx5_rx.h +++ b/drivers/net/mlx5/mlx5_rx.h @@ -185,12 +185,6 @@ struct mlx5_rxq_priv { uint32_t lwm_devx_subscribed:1; }; -/* External RX queue descriptor. */ -struct mlx5_external_q { - uint32_t hw_id; /* Queue index in the Hardware. */ - RTE_ATOMIC(uint32_t) refcnt; /* Reference counter. */ -}; - /* mlx5_rxq.c */ extern uint8_t rss_hash_default_key[]; diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c index d6c84b84e4..f13fc3b353 100644 --- a/drivers/net/mlx5/mlx5_rxq.c +++ b/drivers/net/mlx5/mlx5_rxq.c @@ -3211,6 +3211,7 @@ mlx5_external_rx_queue_get_validate(uint16_t port_id, uint16_t dpdk_idx) { struct rte_eth_dev *dev; struct mlx5_priv *priv; + int ret; if (dpdk_idx < RTE_PMD_MLX5_EXTERNAL_RX_QUEUE_ID_MIN) { DRV_LOG(ERR, "Queue index %u should be in range: [%u, %u].", @@ -3218,28 +3219,11 @@ mlx5_external_rx_queue_get_validate(uint16_t port_id, uint16_t dpdk_idx) rte_errno = EINVAL; return NULL; } - if (rte_eth_dev_is_valid_port(port_id) < 0) { - DRV_LOG(ERR, "There is no Ethernet device for port %u.", - port_id); - rte_errno = ENODEV; + ret = mlx5_devx_extq_port_validate(port_id); + if (unlikely(ret)) return NULL; - } dev = &rte_eth_devices[port_id]; priv = dev->data->dev_private; - if (!mlx5_imported_pd_and_ctx(priv->sh->cdev)) { - DRV_LOG(ERR, "Port %u " - "external RxQ isn't supported on local PD and CTX.", - port_id); - rte_errno = ENOTSUP; - return NULL; - } - if (!mlx5_devx_obj_ops_en(priv->sh)) { - DRV_LOG(ERR, - "Port %u external RxQ isn't supported by Verbs API.", - port_id); - rte_errno = ENOTSUP; - return NULL; - } /* * When user configures remote PD and CTX and device creates RxQ by * DevX, external RxQs array is allocated. diff --git a/drivers/net/mlx5/mlx5_tx.h b/drivers/net/mlx5/mlx5_tx.h index 0d77ff89de..983913faa2 100644 --- a/drivers/net/mlx5/mlx5_tx.h +++ b/drivers/net/mlx5/mlx5_tx.h @@ -227,6 +227,8 @@ void mlx5_txq_dynf_timestamp_set(struct rte_eth_dev *dev); int mlx5_count_aggr_ports(struct rte_eth_dev *dev); int mlx5_map_aggr_tx_affinity(struct rte_eth_dev *dev, uint16_t tx_queue_id, uint8_t affinity); +int mlx5_ext_txq_verify(struct rte_eth_dev *dev); +struct mlx5_external_q *mlx5_ext_txq_get(struct rte_eth_dev *dev, uint16_t idx); /* mlx5_tx.c */ @@ -3788,4 +3790,27 @@ mlx5_tx_burst_tmpl(struct mlx5_txq_data *__rte_restrict txq, return loc.pkts_sent; } +/** + * Check whether given TxQ is external. + * + * @param dev + * Pointer to Ethernet device. + * @param queue_idx + * Tx queue index. + * + * @return + * True if is external TxQ, otherwise false. + */ +static __rte_always_inline bool +mlx5_is_external_txq(struct rte_eth_dev *dev, uint16_t queue_idx) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_external_q *txq; + + if (!priv->ext_txqs || queue_idx < MLX5_EXTERNAL_TX_QUEUE_ID_MIN) + return false; + txq = &priv->ext_txqs[queue_idx - MLX5_EXTERNAL_TX_QUEUE_ID_MIN]; + return !!rte_atomic_load_explicit(&txq->refcnt, rte_memory_order_relaxed); +} + #endif /* RTE_PMD_MLX5_TX_H_ */ diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c index da4236f99a..8eb1ae1f03 100644 --- a/drivers/net/mlx5/mlx5_txq.c +++ b/drivers/net/mlx5/mlx5_txq.c @@ -27,6 +27,7 @@ #include "mlx5_tx.h" #include "mlx5_rxtx.h" #include "mlx5_autoconf.h" +#include "mlx5_devx.h" #include "rte_pmd_mlx5.h" #include "mlx5_flow.h" @@ -1183,6 +1184,57 @@ mlx5_txq_get(struct rte_eth_dev *dev, uint16_t idx) return ctrl; } +/** + * Get an external Tx queue. + * + * @param dev + * Pointer to Ethernet device. + * @param idx + * External Tx queue index. + * + * @return + * A pointer to the queue if it exists, NULL otherwise. + */ +struct mlx5_external_q * +mlx5_ext_txq_get(struct rte_eth_dev *dev, uint16_t idx) +{ + struct mlx5_priv *priv = dev->data->dev_private; + + MLX5_ASSERT(mlx5_is_external_txq(dev, idx)); + return &priv->ext_txqs[idx - MLX5_EXTERNAL_TX_QUEUE_ID_MIN]; +} + +/** + * Verify the external Tx Queue list is empty. + * + * @param dev + * Pointer to Ethernet device. + * + * @return + * The number of object not released. + */ +int +mlx5_ext_txq_verify(struct rte_eth_dev *dev) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_external_q *txq; + uint32_t i; + int ret = 0; + + if (priv->ext_txqs == NULL) + return 0; + + for (i = MLX5_EXTERNAL_TX_QUEUE_ID_MIN; i <= UINT16_MAX ; ++i) { + txq = mlx5_ext_txq_get(dev, i); + if (txq->refcnt < 2) + continue; + DRV_LOG(DEBUG, "Port %u external TxQ %u still referenced.", + dev->data->port_id, i); + ++ret; + } + return ret; +} + /** * Release a Tx queue. * @@ -1416,3 +1468,103 @@ int mlx5_map_aggr_tx_affinity(struct rte_eth_dev *dev, uint16_t tx_queue_id, txq_ctrl->txq.tx_aggr_affinity = affinity; return 0; } + +/** + * Validate given external TxQ rte_flow index, and get pointer to concurrent + * external TxQ object to map/unmap. + * + * @param[in] port_id + * The port identifier of the Ethernet device. + * @param[in] dpdk_idx + * Tx Queue index in rte_flow. + * + * @return + * Pointer to concurrent external TxQ on success, + * NULL otherwise and rte_errno is set. + */ +static struct mlx5_external_q * +mlx5_external_tx_queue_get_validate(uint16_t port_id, uint16_t dpdk_idx) +{ + struct rte_eth_dev *dev; + struct mlx5_priv *priv; + int ret; + + if (dpdk_idx < MLX5_EXTERNAL_TX_QUEUE_ID_MIN) { + DRV_LOG(ERR, "Queue index %u should be in range: [%u, %u].", + dpdk_idx, MLX5_EXTERNAL_TX_QUEUE_ID_MIN, UINT16_MAX); + rte_errno = EINVAL; + return NULL; + } + ret = mlx5_devx_extq_port_validate(port_id); + if (unlikely(ret)) + return NULL; + dev = &rte_eth_devices[port_id]; + priv = dev->data->dev_private; + /* + * When user configures remote PD and CTX and device creates TxQ by + * DevX, external TxQs array is allocated. + */ + MLX5_ASSERT(priv->ext_txqs != NULL); + return &priv->ext_txqs[dpdk_idx - MLX5_EXTERNAL_TX_QUEUE_ID_MIN]; +} + +int +rte_pmd_mlx5_external_tx_queue_id_map(uint16_t port_id, uint16_t dpdk_idx, + uint32_t hw_idx) +{ + struct mlx5_external_q *ext_txq; + uint32_t unmapped = 0; + + ext_txq = mlx5_external_tx_queue_get_validate(port_id, dpdk_idx); + if (ext_txq == NULL) + return -rte_errno; + if (!rte_atomic_compare_exchange_strong_explicit(&ext_txq->refcnt, &unmapped, 1, + rte_memory_order_relaxed, rte_memory_order_relaxed)) { + if (ext_txq->hw_id != hw_idx) { + DRV_LOG(ERR, "Port %u external TxQ index %u " + "is already mapped to HW index (requesting is " + "%u, existing is %u).", + port_id, dpdk_idx, hw_idx, ext_txq->hw_id); + rte_errno = EEXIST; + return -rte_errno; + } + DRV_LOG(WARNING, "Port %u external TxQ index %u " + "is already mapped to the requested HW index (%u)", + port_id, dpdk_idx, hw_idx); + + } else { + ext_txq->hw_id = hw_idx; + DRV_LOG(DEBUG, "Port %u external TxQ index %u " + "is successfully mapped to the requested HW index (%u)", + port_id, dpdk_idx, hw_idx); + } + return 0; +} + +int +rte_pmd_mlx5_external_tx_queue_id_unmap(uint16_t port_id, uint16_t dpdk_idx) +{ + struct mlx5_external_q *ext_txq; + uint32_t mapped = 1; + + ext_txq = mlx5_external_tx_queue_get_validate(port_id, dpdk_idx); + if (ext_txq == NULL) + return -rte_errno; + if (ext_txq->refcnt > 1) { + DRV_LOG(ERR, "Port %u external TxQ index %u still referenced.", + port_id, dpdk_idx); + rte_errno = EINVAL; + return -rte_errno; + } + if (!rte_atomic_compare_exchange_strong_explicit(&ext_txq->refcnt, &mapped, 0, + rte_memory_order_relaxed, rte_memory_order_relaxed)) { + DRV_LOG(ERR, "Port %u external TxQ index %u doesn't exist.", + port_id, dpdk_idx); + rte_errno = EINVAL; + return -rte_errno; + } + DRV_LOG(DEBUG, + "Port %u external TxQ index %u is successfully unmapped.", + port_id, dpdk_idx); + return 0; +} diff --git a/drivers/net/mlx5/rte_pmd_mlx5.h b/drivers/net/mlx5/rte_pmd_mlx5.h index 004be0eea1..359e4192c8 100644 --- a/drivers/net/mlx5/rte_pmd_mlx5.h +++ b/drivers/net/mlx5/rte_pmd_mlx5.h @@ -68,6 +68,11 @@ int rte_pmd_mlx5_sync_flow(uint16_t port_id, uint32_t domains); */ #define RTE_PMD_MLX5_EXTERNAL_RX_QUEUE_ID_MIN (UINT16_MAX - 1000 + 1) +/** + * External Tx queue rte_flow index minimal value. + */ +#define MLX5_EXTERNAL_TX_QUEUE_ID_MIN (UINT16_MAX - 1000 + 1) + /** * Tag level to set the linear hash index. */ @@ -116,6 +121,49 @@ __rte_experimental int rte_pmd_mlx5_external_rx_queue_id_unmap(uint16_t port_id, uint16_t dpdk_idx); +/** + * Update mapping between rte_flow Tx queue index (16 bits) and HW queue index (32 + * bits) for TxQs which is created outside the PMD. + * + * @param[in] port_id + * The port identifier of the Ethernet device. + * @param[in] dpdk_idx + * Queue index in rte_flow. + * @param[in] hw_idx + * Queue index in hardware. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + * Possible values for rte_errno: + * - EEXIST - a mapping with the same rte_flow index already exists. + * - EINVAL - invalid rte_flow index, out of range. + * - ENODEV - there is no Ethernet device for this port id. + * - ENOTSUP - the port doesn't support external TxQ. + */ +__rte_experimental +int rte_pmd_mlx5_external_tx_queue_id_map(uint16_t port_id, uint16_t dpdk_idx, + uint32_t hw_idx); + +/** + * Remove mapping between rte_flow Tx queue index (16 bits) and HW queue index (32 + * bits) for TxQs which is created outside the PMD. + * + * @param[in] port_id + * The port identifier of the Ethernet device. + * @param[in] dpdk_idx + * Queue index in rte_flow. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + * Possible values for rte_errno: + * - EINVAL - invalid index, out of range, still referenced or doesn't exist. + * - ENODEV - there is no Ethernet device for this port id. + * - ENOTSUP - the port doesn't support external TxQ. + */ +__rte_experimental +int rte_pmd_mlx5_external_tx_queue_id_unmap(uint16_t port_id, + uint16_t dpdk_idx); + /** * The rate of the host port shaper will be updated directly at the next * available descriptor threshold event to the rate that comes with this flag set; diff --git a/drivers/net/mlx5/version.map b/drivers/net/mlx5/version.map index 8fb0e07303..8a78d14786 100644 --- a/drivers/net/mlx5/version.map +++ b/drivers/net/mlx5/version.map @@ -20,4 +20,7 @@ EXPERIMENTAL { # added in 24.03 rte_pmd_mlx5_create_geneve_tlv_parser; rte_pmd_mlx5_destroy_geneve_tlv_parser; + # added in 24.07 + rte_pmd_mlx5_external_tx_queue_id_map; + rte_pmd_mlx5_external_tx_queue_id_unmap; }; -- 2.34.1