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 5197BA0C4D; Fri, 3 Sep 2021 02:16:05 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2456840DFD; Fri, 3 Sep 2021 02:16:00 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 1942F40041 for ; Fri, 3 Sep 2021 02:15:57 +0200 (CEST) Received: from localhost.localdomain (unknown [5.144.122.241]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by shelob.oktetlabs.ru (Postfix) with ESMTPSA id 9930E7F609; Fri, 3 Sep 2021 03:15:56 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 9930E7F609 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=oktetlabs.ru; s=default; t=1630628156; bh=W0jSsjeHHSEFCKHdJZARA73LfiCbZj5fBPaKRnu6X1o=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=N/WsX2tPrJ5G6p5wOYnEILMv/lfX9YfwWpVFZuP/N6Dg+wrtLdt8ZGsNubkLAlzrb J2kJiswBKJ0iK6mm8iyhWTDIugp942vFDtjnKvRDq0qcfPJXzMyGRvbPf59THYtheg acoIvzSXwPeu6KKrLn3iAndaLvAhgzVgUWwV/fAs= From: Ivan Malov To: dev@dpdk.org Cc: Jerin Jacob , Ray Kinsella , Andrew Rybchenko , Wisam Jaddo , Xiaoyun Li , Thomas Monjalon , Ferruh Yigit , Ori Kam Date: Fri, 3 Sep 2021 03:15:38 +0300 Message-Id: <20210903001542.15309-2-ivan.malov@oktetlabs.ru> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210903001542.15309-1-ivan.malov@oktetlabs.ru> References: <20210902142359.28138-1-ivan.malov@oktetlabs.ru> <20210903001542.15309-1-ivan.malov@oktetlabs.ru> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH v2 1/5] ethdev: add API to negotiate support for Rx meta information 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" Per-packet meta information (flag, mark and the likes) might be expensive to deliver in terms of small packet performance. If the features are not enabled by default, enabling them at short notice (for example, when a flow rule with action MARK gets created) without traffic disruption may not be possible. Letting applications request delivery of Rx meta information during initialisation can solve the said problem efficiently. Technically, that could be accomplished by defining new bits in DEV_RX_OFFLOAD namespace, but the ability to extract meta data cannot be considered an offload on its own. For example, Rx checksumming is an offload, while mark delivery is not as it needs an external party, a flow rule with action MARK, to hold the value and trigger mark insertion in the first place. With this in mind, add a means to let applications negotiate adapter support for the very delivery of Rx meta information. Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Acked-by: Ray Kinsella --- app/test-flow-perf/main.c | 21 ++++++++ app/test-pmd/testpmd.c | 26 ++++++++++ doc/guides/rel_notes/release_21_11.rst | 10 ++++ lib/ethdev/ethdev_driver.h | 19 ++++++++ lib/ethdev/rte_ethdev.c | 25 ++++++++++ lib/ethdev/rte_ethdev.h | 66 ++++++++++++++++++++++++++ lib/ethdev/rte_flow.h | 15 ++++++ lib/ethdev/version.map | 3 ++ 8 files changed, 185 insertions(+) diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c index 9be8edc31d..48eafffb1d 100644 --- a/app/test-flow-perf/main.c +++ b/app/test-flow-perf/main.c @@ -1760,6 +1760,27 @@ init_port(void) rte_exit(EXIT_FAILURE, "Error: can't init mbuf pool\n"); for (port_id = 0; port_id < nr_ports; port_id++) { + uint64_t rx_meta_features = 0; + + rx_meta_features |= RTE_ETH_RX_META_USER_FLAG; + rx_meta_features |= RTE_ETH_RX_META_USER_MARK; + + ret = rte_eth_rx_meta_negotiate(port_id, &rx_meta_features); + if (ret == 0) { + if (!(rx_meta_features & RTE_ETH_RX_META_USER_FLAG)) { + printf(":: flow action FLAG will not affect Rx mbufs on port=%u\n", + port_id); + } + + if (!(rx_meta_features & RTE_ETH_RX_META_USER_MARK)) { + printf(":: flow action MARK will not affect Rx mbufs on port=%u\n", + port_id); + } + } else if (ret != -ENOTSUP) { + rte_exit(EXIT_FAILURE, "Error when negotiating Rx meta features on port=%u: %s\n", + port_id, rte_strerror(-ret)); + } + ret = rte_eth_dev_info_get(port_id, &dev_info); if (ret != 0) rte_exit(EXIT_FAILURE, diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 9061cbf637..72addc59db 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -1421,10 +1421,36 @@ static void init_config_port_offloads(portid_t pid, uint32_t socket_id) { struct rte_port *port = &ports[pid]; + uint64_t rx_meta_features = 0; uint16_t data_size; int ret; int i; + rx_meta_features |= RTE_ETH_RX_META_USER_FLAG; + rx_meta_features |= RTE_ETH_RX_META_USER_MARK; + rx_meta_features |= RTE_ETH_RX_META_TUNNEL_ID; + + ret = rte_eth_rx_meta_negotiate(pid, &rx_meta_features); + if (ret == 0) { + if (!(rx_meta_features & RTE_ETH_RX_META_USER_FLAG)) { + TESTPMD_LOG(INFO, "Flow action FLAG will not affect Rx mbufs on port %u\n", + pid); + } + + if (!(rx_meta_features & RTE_ETH_RX_META_USER_MARK)) { + TESTPMD_LOG(INFO, "Flow action MARK will not affect Rx mbufs on port %u\n", + pid); + } + + if (!(rx_meta_features & RTE_ETH_RX_META_TUNNEL_ID)) { + TESTPMD_LOG(INFO, "Flow tunnel offload support might be limited or unavailable on port %u\n", + pid); + } + } else if (ret != -ENOTSUP) { + rte_exit(EXIT_FAILURE, "Error when negotiating Rx meta features on port %u: %s\n", + pid, rte_strerror(-ret)); + } + port->dev_conf.txmode = tx_mode; port->dev_conf.rxmode = rx_mode; diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index d707a554ef..017b5a8239 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -55,6 +55,16 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Added an API to negotiate support for Rx meta information** + + A new API, ``rte_eth_rx_meta_negotiate()``, was added to let applications + negotiate support for the very delivery of various Rx meta data fractions, + with the following definitions being available starting from this release: + + * ``RTE_ETH_RX_META_USER_FLAG`` + * ``RTE_ETH_RX_META_USER_MARK`` + * ``RTE_ETH_RX_META_TUNNEL_ID`` + Removed Items ------------- diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index 40e474aa7e..508d2e6bfb 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -789,6 +789,22 @@ typedef int (*eth_get_monitor_addr_t)(void *rxq, typedef int (*eth_representor_info_get_t)(struct rte_eth_dev *dev, struct rte_eth_representor_info *info); +/** + * @internal + * Negotiate support for specific fractions of Rx meta information. + * + * @param dev + * Port (ethdev) handle + * + * @param[inout] features + * Feature selection buffer + * + * @return + * Negative errno value on error, zero otherwise + */ +typedef int (*eth_rx_meta_negotiate_t)(struct rte_eth_dev *dev, + uint64_t *features); + /** * @internal A structure containing the functions exported by an Ethernet driver. */ @@ -949,6 +965,9 @@ struct eth_dev_ops { eth_representor_info_get_t representor_info_get; /**< Get representor info. */ + + eth_rx_meta_negotiate_t rx_meta_negotiate; + /**< Negotiate support for specific fractions of Rx meta information. */ }; /** diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 9d95cd11e1..8010aa7a43 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -6311,6 +6311,31 @@ rte_eth_representor_info_get(uint16_t port_id, return eth_err(port_id, (*dev->dev_ops->representor_info_get)(dev, info)); } +int +rte_eth_rx_meta_negotiate(uint16_t port_id, uint64_t *features) +{ + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + + if (dev->data->dev_configured != 0) { + RTE_ETHDEV_LOG(ERR, + "The port (id=%"PRIu16") is already configured\n", + port_id); + return -EBUSY; + } + + if (features == NULL) { + RTE_ETHDEV_LOG(ERR, "Invalid features (NULL)\n"); + return -EINVAL; + } + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_meta_negotiate, -ENOTSUP); + return eth_err(port_id, + (*dev->dev_ops->rx_meta_negotiate)(dev, features)); +} + RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO); RTE_INIT(ethdev_init_telemetry) diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index d2b27c351f..16af376866 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -4888,6 +4888,72 @@ __rte_experimental int rte_eth_representor_info_get(uint16_t port_id, struct rte_eth_representor_info *info); +/** + * The ethdev will be able to detect flagged packets provided that + * there are active flow rules comprising the corresponding action. + */ +#define RTE_ETH_RX_META_USER_FLAG (UINT64_C(1) << 0) + +/** + * The ethdev will manage to see mark IDs in packets provided that + * there are active flow rules comprising the corresponding action. + */ +#define RTE_ETH_RX_META_USER_MARK (UINT64_C(1) << 1) + +/** + * The ethdev will be able to identify partially offloaded packets + * and process rte_flow_get_restore_info() invocations accordingly + * provided that there're so-called "tunnel_set" flow rules in use. + */ +#define RTE_ETH_RX_META_TUNNEL_ID (UINT64_C(1) << 2) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Negotiate support for specific fractions of Rx meta information. + * + * This function has to be invoked as early as possible, precisely, + * before the first rte_eth_dev_configure() invocation, to let the + * PMD make preparations which might be hard to do on later stages. + * + * The negotiation process is assumed to be carried out as follows: + * + * - the application composes a mask of preferred Rx meta features + * intending to enable at least some of them and invokes the API; + * + * - the ethdev driver reports back the optimal (from its point of + * view) subset of the initial feature set thus agreeing to make + * those comprising the subset simultaneously available to users; + * + * - should the application find the result unsatisfactory, it may + * come up with another pick of preferred features and try again; + * + * - the application can pass zero to clear the negotiation result; + * + * - the last negotiated result takes effect upon the ethdev start. + * + * If the method itself is unsupported by the PMD, the application + * may just ignore that and proceed with the rest of configuration + * procedure intending to simply try using the features it prefers. + * + * @param port_id + * Port (ethdev) identifier + * + * @param[inout] features + * Feature selection buffer + * + * @return + * - (-EBUSY) if the port can't handle this in its current state; + * - (-ENOTSUP) if the method itself is not supported by the PMD; + * - (-ENODEV) if *port_id* is invalid; + * - (-EINVAL) if *features* is NULL; + * - (-EIO) if the device is removed; + * - (0) on success + */ +__rte_experimental +int rte_eth_rx_meta_negotiate(uint16_t port_id, uint64_t *features); + #include /** diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index 70f455d47d..f8f2bc2e8c 100644 --- a/lib/ethdev/rte_flow.h +++ b/lib/ethdev/rte_flow.h @@ -1904,6 +1904,11 @@ enum rte_flow_action_type { * PKT_RX_FDIR_ID mbuf flags. * * See struct rte_flow_action_mark. + * + * The ethdev's ability to serve mark IDs with received packets + * has to be negotiated separately during initialisation period. + * @see rte_eth_rx_meta_negotiate() + * @see RTE_ETH_RX_META_USER_MARK */ RTE_FLOW_ACTION_TYPE_MARK, @@ -1912,6 +1917,11 @@ enum rte_flow_action_type { * sets the PKT_RX_FDIR mbuf flag. * * No associated configuration structure. + * + * The ethdev's ability to serve the flag with received packets + * has to be negotiated separately during initialisation period. + * @see rte_eth_rx_meta_negotiate() + * @see RTE_ETH_RX_META_USER_FLAG */ RTE_FLOW_ACTION_TYPE_FLAG, @@ -4223,6 +4233,11 @@ rte_flow_tunnel_match(uint16_t port_id, /** * Populate the current packet processing state, if exists, for the given mbuf. * + * The ethdev's ability to uncover such packet processing state + * has to be negotiated separately during initialisation period. + * @see rte_eth_rx_meta_negotiate() + * @see RTE_ETH_RX_META_TUNNEL_ID + * * @param port_id * Port identifier of Ethernet device. * @param[in] m diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map index 3eece75b72..2cf773f63a 100644 --- a/lib/ethdev/version.map +++ b/lib/ethdev/version.map @@ -249,6 +249,9 @@ EXPERIMENTAL { rte_mtr_meter_policy_delete; rte_mtr_meter_policy_update; rte_mtr_meter_policy_validate; + + # added in 21.11 + rte_eth_rx_meta_negotiate; }; INTERNAL { -- 2.20.1