From patchwork Thu Oct 8 08:51:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bing Zhao X-Patchwork-Id: 79993 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 81B9DA04BC; Thu, 8 Oct 2020 10:52:10 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 456721BB4F; Thu, 8 Oct 2020 10:51:59 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 9F7451BB40 for ; Thu, 8 Oct 2020 10:51:56 +0200 (CEST) From: Bing Zhao To: thomas@monjalon.net, orika@nvidia.com, ferruh.yigit@intel.com, arybchenko@solarflare.com, mdr@ashroe.eu, nhorman@tuxdriver.com, bernard.iremonger@intel.com, beilei.xing@intel.com, wenzhuo.lu@intel.com Cc: dev@dpdk.org Date: Thu, 8 Oct 2020 16:51:33 +0800 Message-Id: <1602147098-9768-2-git-send-email-bingz@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1602147098-9768-1-git-send-email-bingz@nvidia.com> References: <1601511962-21532-1-git-send-email-bingz@nvidia.com> <1602147098-9768-1-git-send-email-bingz@nvidia.com> Subject: [dpdk-dev] [PATCH v2 1/6] ethdev: add hairpin bind and unbind APIs X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" In single port hairpin mode, all the hairpin TX and RX queues belong to the same device. After the queues are set up properly, there is no other dependency between the TX queue and its RX peer queue. The binding process that connected the TX and RX queues together from hardware level will be done automatically during the device start procedure. Everything required is configured and initialized already for the binding process. But in two ports hairpin mode, there will be some cross-dependences between two different ports. Usually, the ports will be initialized serially by the main thread but not in parallel. The earlier port will not be able to enable the bind if the following peer port is not yet configured with HW resources. What's more, if one port is detached / attached dynamically, it would introduce more trouble for the hairpin binding. To overcome these, new APIs for binding and unbinding are added. During startup, only the hairpin TX and RX peer queues will be set up. Nothing will be done when starting the device if the queues are without auto-bind attribute. Only after the required ports pair started, the `rte_eth_hairpin_bind()` API can be called to bind the all TX queues of the egress port to the RX queues of the peer port. Then the connection between the egress and ingress ports pair will be established. The `rte_eth_hairpin_unbind()` API could be used to disconnect the egress and the peer ingress ports. This should only be called before the device is closed if needed. When doing the clean up, all the egress and ingress pairs related to a single port should be taken into consideration, especially in the hot unplug case. Signed-off-by: Bing Zhao Acked-by: Ori Kam --- v2: remove the all peer ports logic from rte API --- lib/librte_ethdev/rte_ethdev.c | 46 ++++++++++++++++++++++++++++ lib/librte_ethdev/rte_ethdev.h | 51 +++++++++++++++++++++++++++++++ lib/librte_ethdev/rte_ethdev_driver.h | 52 ++++++++++++++++++++++++++++++++ lib/librte_ethdev/rte_ethdev_version.map | 2 ++ 4 files changed, 151 insertions(+) diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index 0f56541..85a19bd 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -2162,6 +2162,52 @@ struct rte_eth_dev * return eth_err(port_id, ret); } +int +rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port) +{ + struct rte_eth_dev *dev; + int ret; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -EINVAL); + dev = &rte_eth_devices[tx_port]; + if (!dev->data->dev_started) { + RTE_ETHDEV_LOG(ERR, "TX port %d is not started", tx_port); + return -EBUSY; + } + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_bind, -ENOTSUP); + ret = (*dev->dev_ops->hairpin_bind)(dev, rx_port); + if (ret) + RTE_ETHDEV_LOG(ERR, "Failed to bind hairpin TX %d " + "to RX %d (%d - all ports)", tx_port, + rx_port, RTE_MAX_ETHPORTS); + + return ret; +} + +int +rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port) +{ + struct rte_eth_dev *dev; + int ret; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -EINVAL); + dev = &rte_eth_devices[tx_port]; + if (!dev->data->dev_started) { + RTE_ETHDEV_LOG(ERR, "TX port %d is already stopped", tx_port); + return -EBUSY; + } + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_unbind, -ENOTSUP); + ret = (*dev->dev_ops->hairpin_unbind)(dev, rx_port); + if (ret) + RTE_ETHDEV_LOG(ERR, "Failed to unbind hairpin " + "TX %d from RX %d (%d - all ports)", tx_port, + rx_port, RTE_MAX_ETHPORTS); + + return ret; +} + void rte_eth_tx_buffer_drop_callback(struct rte_mbuf **pkts, uint16_t unsent, void *userdata __rte_unused) diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h index d2bf74f..6206643 100644 --- a/lib/librte_ethdev/rte_ethdev.h +++ b/lib/librte_ethdev/rte_ethdev.h @@ -2128,6 +2128,57 @@ int rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id, const struct rte_eth_hairpin_conf *conf); /** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Bind all hairpin TX queues of one port to the RX queues of the peer port. + * It is only allowed to call this API after all hairpin queues are configured + * properly and the devices of TX and peer RX are in started state. + * + * @param tx_port + * The TX port identifier of the Ethernet device. + * @param rx_port + * The peer RX port identifier of the Ethernet device. + * RTE_MAX_ETHPORTS is allowed for the traversal of all devices. + * RX port ID could have the same value with TX port ID. + * + * @return + * - (0) if successful. + * - (-EINVAL) if bad parameter. + * - (-EBUSY) if device is not in started state. + * - (-ENOTSUP) if hardware doesn't support. + * - Others detailed errors from PMD drivers. + */ +__rte_experimental +int rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port); + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Unbind all hairpin TX queues of one port from the RX queues of the peer port. + * This should be called before closing the TX or RX devices (optional). After + * unbind the hairpin ports pair, it is allowed to bind them again. + * Changing queues configuration should be after stopping the device. + * + * @param tx_port + * The TX port identifier of the Ethernet device. + * @param rx_port + * The peer RX port identifier of the Ethernet device. + * RTE_MAX_ETHPORTS is allowed for traversal of all devices. + * RX port ID could have the same value with TX port ID. + * + * @return + * - (0) if successful. + * - (-EINVAL) if bad parameter. + * - (-EBUSY) if device is in stopped state. + * - (-ENOTSUP) if hardware doesn't support. + * - Others detailed errors from PMD drivers. + */ +__rte_experimental +int rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port); + +/** * Return the NUMA socket to which an Ethernet device is connected * * @param port_id diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h index c3062c2..f8eb879 100644 --- a/lib/librte_ethdev/rte_ethdev_driver.h +++ b/lib/librte_ethdev/rte_ethdev_driver.h @@ -575,6 +575,54 @@ typedef int (*eth_tx_hairpin_queue_setup_t) const struct rte_eth_hairpin_conf *hairpin_conf); /** + * @internal + * Bind all hairpin TX queues of one port to the RX queues of the peer port. + * + * @param dev + * ethdev handle of port. + * @param rx_port + * the peer RX port. + * + * @return + * Negative errno value on error, 0 on success. + * + * @retval 0 + * Success, bind successfully. + * @retval -ENOTSUP + * Bind API is not supported. + * @retval -EINVAL + * One of the parameters is invalid. + * @retval -EBUSY + * Device is not started. + */ +typedef int (*eth_hairpin_bind_t)(struct rte_eth_dev *dev, + uint16_t rx_port); + +/** + * @internal + * Unbind all hairpin TX queues of one port from the RX queues of the peer port. + * + * @param dev + * ethdev handle of port. + * @param rx_port + * the peer RX port. + * + * @return + * Negative errno value on error, 0 on success. + * + * @retval 0 + * Success, bind successfully. + * @retval -ENOTSUP + * Bind API is not supported. + * @retval -EINVAL + * One of the parameters is invalid. + * @retval -EBUSY + * Device is already stopped. + */ +typedef int (*eth_hairpin_unbind_t)(struct rte_eth_dev *dev, + uint16_t rx_port); + +/** * @internal A structure containing the functions exported by an Ethernet driver. */ struct eth_dev_ops { @@ -713,6 +761,10 @@ struct eth_dev_ops { /**< Set up device RX hairpin queue. */ eth_tx_hairpin_queue_setup_t tx_hairpin_queue_setup; /**< Set up device TX hairpin queue. */ + eth_hairpin_bind_t hairpin_bind; + /**< Bind all hairpin TX queues of device to the peer port RX queues. */ + eth_hairpin_unbind_t hairpin_unbind; + /**< Unbind all hairpin TX queues from the peer port RX queues. */ }; /** diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map index c95ef51..18efe4e 100644 --- a/lib/librte_ethdev/rte_ethdev_version.map +++ b/lib/librte_ethdev/rte_ethdev_version.map @@ -227,6 +227,8 @@ EXPERIMENTAL { rte_tm_wred_profile_delete; # added in 20.11 + rte_eth_hairpin_bind; + rte_eth_hairpin_unbind; rte_eth_link_speed_to_str; rte_eth_link_to_str; }; From patchwork Thu Oct 8 08:51:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bing Zhao X-Patchwork-Id: 79994 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 57102A04BC; Thu, 8 Oct 2020 10:52:29 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E85151BBD1; Thu, 8 Oct 2020 10:52:03 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 7724E1BB71 for ; Thu, 8 Oct 2020 10:52:00 +0200 (CEST) From: Bing Zhao To: thomas@monjalon.net, orika@nvidia.com, ferruh.yigit@intel.com, arybchenko@solarflare.com, mdr@ashroe.eu, nhorman@tuxdriver.com, bernard.iremonger@intel.com, beilei.xing@intel.com, wenzhuo.lu@intel.com Cc: dev@dpdk.org Date: Thu, 8 Oct 2020 16:51:34 +0800 Message-Id: <1602147098-9768-3-git-send-email-bingz@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1602147098-9768-1-git-send-email-bingz@nvidia.com> References: <1601511962-21532-1-git-send-email-bingz@nvidia.com> <1602147098-9768-1-git-send-email-bingz@nvidia.com> Subject: [dpdk-dev] [PATCH v2 2/6] ethdev: add new attributes to hairpin config X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" To support two ports hairpin mode and keep the backward compatibility for the application, two new attribute members of hairpin queue configuration structure are added. `tx_explicit` means if the application itself will insert the TX part flow rules. If not set, PMD will insert the rules implicitly. `manual_bind` means if the hairpin TX queue and peer RX queue will be bound automatically during device start stage. Different TX and RX queue pairs could have different values, but it is highly recommended that all paired queues between one egress and its peer ingress ports have the same values, in order not to bring any chaos to the system. The actual support of these attribute parameters will be checked and decided by the PMD drivers. In a single port hairpin, if both are zero without any setting, the behavior will remain the same as before. It means no bind API needs to be called and no TX flow rules need to be inserted manually by the application. Signed-off-by: Bing Zhao Acked-by: Ori Kam --- v2: optimize the structure and remove unused macros --- lib/librte_ethdev/rte_ethdev.c | 8 ++++---- lib/librte_ethdev/rte_ethdev.h | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index 85a19bd..a4adeff 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -1954,13 +1954,13 @@ struct rte_eth_dev * } if (conf->peer_count > cap.max_rx_2_tx) { RTE_ETHDEV_LOG(ERR, - "Invalid value for number of peers for Rx queue(=%hu), should be: <= %hu", + "Invalid value for number of peers for Rx queue(=%u), should be: <= %hu", conf->peer_count, cap.max_rx_2_tx); return -EINVAL; } if (conf->peer_count == 0) { RTE_ETHDEV_LOG(ERR, - "Invalid value for number of peers for Rx queue(=%hu), should be: > 0", + "Invalid value for number of peers for Rx queue(=%u), should be: > 0", conf->peer_count); return -EINVAL; } @@ -2125,13 +2125,13 @@ struct rte_eth_dev * } if (conf->peer_count > cap.max_tx_2_rx) { RTE_ETHDEV_LOG(ERR, - "Invalid value for number of peers for Tx queue(=%hu), should be: <= %hu", + "Invalid value for number of peers for Tx queue(=%u), should be: <= %hu", conf->peer_count, cap.max_tx_2_rx); return -EINVAL; } if (conf->peer_count == 0) { RTE_ETHDEV_LOG(ERR, - "Invalid value for number of peers for Tx queue(=%hu), should be: > 0", + "Invalid value for number of peers for Tx queue(=%u), should be: > 0", conf->peer_count); return -EINVAL; } diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h index 6206643..94a981c 100644 --- a/lib/librte_ethdev/rte_ethdev.h +++ b/lib/librte_ethdev/rte_ethdev.h @@ -1045,7 +1045,10 @@ struct rte_eth_hairpin_peer { * A structure used to configure hairpin binding. */ struct rte_eth_hairpin_conf { - uint16_t peer_count; /**< The number of peers. */ + uint32_t peer_count:16; /**< The number of peers. */ + uint32_t tx_explicit:1; /**< Explicit TX flow rule mode. */ + uint32_t manual_bind:1; /**< Manually bind hairpin queues. */ + uint32_t reserved:14; /**< Reserved bits. */ struct rte_eth_hairpin_peer peers[RTE_ETH_MAX_HAIRPIN_PEERS]; }; From patchwork Thu Oct 8 08:51:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bing Zhao X-Patchwork-Id: 79995 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id D8987A04BC; Thu, 8 Oct 2020 10:52:48 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 326FB1BC0C; Thu, 8 Oct 2020 10:52:09 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 502E41BBD7 for ; Thu, 8 Oct 2020 10:52:04 +0200 (CEST) From: Bing Zhao To: thomas@monjalon.net, orika@nvidia.com, ferruh.yigit@intel.com, arybchenko@solarflare.com, mdr@ashroe.eu, nhorman@tuxdriver.com, bernard.iremonger@intel.com, beilei.xing@intel.com, wenzhuo.lu@intel.com Cc: dev@dpdk.org Date: Thu, 8 Oct 2020 16:51:35 +0800 Message-Id: <1602147098-9768-4-git-send-email-bingz@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1602147098-9768-1-git-send-email-bingz@nvidia.com> References: <1601511962-21532-1-git-send-email-bingz@nvidia.com> <1602147098-9768-1-git-send-email-bingz@nvidia.com> Subject: [dpdk-dev] [PATCH v2 3/6] ethdev: add API to get hairpin peer ports list X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" After hairpin queues are configured, in general, the application will maintain the ports topology and even the queues configuration for hairpin. But sometimes it will not. If there is no hot-plug, it is easy to bind and unbind hairpin among all the ports. The application can just connect or disconnect the hairpin egress ports to / from all the probed ingress ports. Then all the connections could be handled properly. But with hot-plug / hot-unplug, one port could be probed and removed dynamically. With two ports hairpin, all the connections from and to this port should be handled after start(bind) or before stop(unbind). It is necessary to know the hairpin topology with this port. This API will return the ports list with the actual peer ports number after configuration. Either peer RX or TX ports will be gotten with this function call. Signed-off-by: Bing Zhao --- lib/librte_ethdev/rte_ethdev.c | 24 ++++++++++++++++++++++++ lib/librte_ethdev/rte_ethdev.h | 27 +++++++++++++++++++++++++++ lib/librte_ethdev/rte_ethdev_driver.h | 30 ++++++++++++++++++++++++++++++ lib/librte_ethdev/rte_ethdev_version.map | 1 + 4 files changed, 82 insertions(+) diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index a4adeff..ea7892a 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -2208,6 +2208,30 @@ struct rte_eth_dev * return ret; } +int +rte_eth_hairpin_get_peer_ports(uint16_t cur_port, uint16_t *peer_ports, + bool direction) +{ + struct rte_eth_dev *dev; + int ret; + + if (!peer_ports) + return -EINVAL; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(cur_port, -EINVAL); + dev = &rte_eth_devices[cur_port]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_get_peer_ports, + -ENOTSUP); + + ret = (*dev->dev_ops->hairpin_get_peer_ports)(dev, peer_ports, + direction); + if (ret < 0) + RTE_ETHDEV_LOG(ERR, "Failed to get %d hairpin peer %s ports", + cur_port, direction ? "RX" : "TX"); + + return ret; +} + void rte_eth_tx_buffer_drop_callback(struct rte_mbuf **pkts, uint16_t unsent, void *userdata __rte_unused) diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h index 94a981c..6680de2 100644 --- a/lib/librte_ethdev/rte_ethdev.h +++ b/lib/librte_ethdev/rte_ethdev.h @@ -2134,6 +2134,33 @@ int rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id, * @warning * @b EXPERIMENTAL: this API may change, or be removed, without prior notice * + * Get all the hairpin peer RX / TX ports of the current port. + * The caller should ensure that the array is large enough to save the ports + * list. + * + * @param cur_port + * The current port identifier of the Ethernet device. + * @param peer_ports + * Pointer to the array to save the peer ports list * + * @param direction + * Current port to peer port direction + * true - current used as TX to get all peer RX ports. + * false - current used as RX to get all peer TX ports. + * + * @return + * - (0 or positive) actual peer ports number. + * - (-EINVAL) if bad parameter. + * - (-ENOTSUP) if hardware doesn't support. + * - Others detailed errors from PMD drivers. + */ +__rte_experimental +int rte_eth_hairpin_get_peer_ports(uint16_t cur_port, uint16_t *peer_ports, + bool direction); + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * * Bind all hairpin TX queues of one port to the RX queues of the peer port. * It is only allowed to call this API after all hairpin queues are configured * properly and the devices of TX and peer RX are in started state. diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h index f8eb879..ecca9d6 100644 --- a/lib/librte_ethdev/rte_ethdev_driver.h +++ b/lib/librte_ethdev/rte_ethdev_driver.h @@ -576,6 +576,34 @@ typedef int (*eth_tx_hairpin_queue_setup_t) /** * @internal + * Get all hairpin TX/RX peer ports of the current device, if any. + * + * @param dev + * ethdev handle of port. + * @param peer_ports + * array to save the ports list. + * @param direction + * value to decide the current to peer direction + * true - used as TX to get all peer RX ports. + * false - used as RX to get all peer TX ports. + * + * @return + * Negative errno value on error, 0 or positive on success. + * + * @retval 0 + * Success, no peer ports. + * @retval >0 + * Actual number of the peer ports. + * @retval -ENOTSUP + * Get peer ports API is not supported. + * @retval -EINVAL + * One of the parameters is invalid. + */ +typedef int (*hairpin_get_peer_ports_t)(struct rte_eth_dev *dev, + uint16_t *peer_ports, bool direction); + +/** + * @internal * Bind all hairpin TX queues of one port to the RX queues of the peer port. * * @param dev @@ -761,6 +789,8 @@ struct eth_dev_ops { /**< Set up device RX hairpin queue. */ eth_tx_hairpin_queue_setup_t tx_hairpin_queue_setup; /**< Set up device TX hairpin queue. */ + hairpin_get_peer_ports_t hairpin_get_peer_ports; + /**< Get hairpin peer ports list. */ eth_hairpin_bind_t hairpin_bind; /**< Bind all hairpin TX queues of device to the peer port RX queues. */ eth_hairpin_unbind_t hairpin_unbind; diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map index 18efe4e..1019e28 100644 --- a/lib/librte_ethdev/rte_ethdev_version.map +++ b/lib/librte_ethdev/rte_ethdev_version.map @@ -228,6 +228,7 @@ EXPERIMENTAL { # added in 20.11 rte_eth_hairpin_bind; + rte_eth_hairpin_get_peer_ports; rte_eth_hairpin_unbind; rte_eth_link_speed_to_str; rte_eth_link_to_str; From patchwork Thu Oct 8 08:51:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bing Zhao X-Patchwork-Id: 79996 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7447EA04BC; Thu, 8 Oct 2020 10:53:07 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id F0EF61BC1C; Thu, 8 Oct 2020 10:52:14 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 0FBA21BBEE for ; Thu, 8 Oct 2020 10:52:08 +0200 (CEST) From: Bing Zhao To: thomas@monjalon.net, orika@nvidia.com, ferruh.yigit@intel.com, arybchenko@solarflare.com, mdr@ashroe.eu, nhorman@tuxdriver.com, bernard.iremonger@intel.com, beilei.xing@intel.com, wenzhuo.lu@intel.com Cc: dev@dpdk.org Date: Thu, 8 Oct 2020 16:51:36 +0800 Message-Id: <1602147098-9768-5-git-send-email-bingz@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1602147098-9768-1-git-send-email-bingz@nvidia.com> References: <1601511962-21532-1-git-send-email-bingz@nvidia.com> <1602147098-9768-1-git-send-email-bingz@nvidia.com> Subject: [dpdk-dev] [PATCH v2 4/6] ethdev: add APIs for hairpin queue operation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" Every hairpin queue pair should be configured properly and the connection between TX and RX queues should be established, before hairpin function works. In single port hairpin mode, the queues of each pair belong to the same device. It is easy to get the hardware and software information of each queue and configure the hairpin connection with such information. In two ports hairpin mode, it is not easy or inappropriate to access one queue's information from another device. Since hairpin is configured per queue pair, three new APIs are introduced and they are internal for the PMD using. The peer update API helps to pass one queue's information to the peer queue and get the peer's information back for the next step. The peer bind API configures the current queue with the peer's information. For each hairpin queue pair, this API may need to be called twice to configure the TX, RX queues separately. The peer unbind API resets the current queue configuration and state to disconnect it from the peer queue. Also, it may need to be called twice to disconnect TX, RX queues from each other. Some parameter of the above APIs might not be mandatory, and it depends on the PMD implementation. The structure of `rte_hairpin_peer_info` is only a declaration and the actual members will be defined in each PMD when being used. Signed-off-by: Bing Zhao Acked-by: Ori Kam --- lib/librte_ethdev/rte_ethdev.c | 55 +++++++++++++++++ lib/librte_ethdev/rte_ethdev_driver.h | 102 +++++++++++++++++++++++++++++++ lib/librte_ethdev/rte_ethdev_version.map | 3 + 3 files changed, 160 insertions(+) diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index ea7892a..4a77497 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -5459,6 +5459,61 @@ enum rte_eth_switch_domain_state { return 0; } +int +rte_eth_hairpin_queue_peer_update(uint16_t peer_port, uint16_t peer_queue, + struct rte_hairpin_peer_info *cur_info, + struct rte_hairpin_peer_info *peer_info, + bool direction) +{ + struct rte_eth_dev *dev; + + /* Current queue information is not mandatory. */ + if (peer_info == NULL) + return -EINVAL; + + /* No need to check the validity again. */ + dev = &rte_eth_devices[peer_port]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_update, + -ENOTSUP); + + return (*dev->dev_ops->hairpin_queue_peer_update)(dev, peer_queue, + cur_info, peer_info, direction); +} + +int +rte_eth_hairpin_queue_peer_bind(uint16_t cur_port, uint16_t cur_queue, + struct rte_hairpin_peer_info *peer_info, + bool direction) +{ + struct rte_eth_dev *dev; + + if (peer_info == NULL) + return -EINVAL; + + /* No need to check the validity again. */ + dev = &rte_eth_devices[cur_port]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_bind, + -ENOTSUP); + + return (*dev->dev_ops->hairpin_queue_peer_bind)(dev, cur_queue, + peer_info, direction); +} + +int +rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue, + bool direction) +{ + struct rte_eth_dev *dev; + + /* No need to check the validity again. */ + dev = &rte_eth_devices[cur_port]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_unbind, + -ENOTSUP); + + return (*dev->dev_ops->hairpin_queue_peer_unbind)(dev, cur_queue, + direction); +} + RTE_LOG_REGISTER(rte_eth_dev_logtype, lib.ethdev, INFO); RTE_INIT(ethdev_init_telemetry) diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h index ecca9d6..713b82d 100644 --- a/lib/librte_ethdev/rte_ethdev_driver.h +++ b/lib/librte_ethdev/rte_ethdev_driver.h @@ -21,6 +21,9 @@ extern "C" { #endif +/**< @internal Declaration of the hairpin peer queue information structure. */ +struct rte_hairpin_peer_info; + /* * Definitions of all functions exported by an Ethernet driver through the * generic structure of type *eth_dev_ops* supplied in the *rte_eth_dev* @@ -650,6 +653,21 @@ typedef int (*eth_hairpin_bind_t)(struct rte_eth_dev *dev, typedef int (*eth_hairpin_unbind_t)(struct rte_eth_dev *dev, uint16_t rx_port); +typedef int (*eth_hairpin_queue_peer_update_t) + (struct rte_eth_dev *dev, uint16_t peer_queue, + struct rte_hairpin_peer_info *current_info, + struct rte_hairpin_peer_info *peer_info, bool direction); +/**< @internal Update and fetch peer queue information. */ + +typedef int (*eth_hairpin_queue_peer_bind_t) + (struct rte_eth_dev *dev, uint16_t cur_queue, + struct rte_hairpin_peer_info *peer_info, bool direction); +/**< @internal Bind peer queue to the current queue with fetched information. */ + +typedef int (*eth_hairpin_queue_peer_unbind_t) + (struct rte_eth_dev *dev, uint16_t cur_queue, bool direction); +/**< @internal Unbind peer queue from the current queue. */ + /** * @internal A structure containing the functions exported by an Ethernet driver. */ @@ -795,6 +813,12 @@ struct eth_dev_ops { /**< Bind all hairpin TX queues of device to the peer port RX queues. */ eth_hairpin_unbind_t hairpin_unbind; /**< Unbind all hairpin TX queues from the peer port RX queues. */ + eth_hairpin_queue_peer_update_t hairpin_queue_peer_update; + /**< Pass the current queue info and get the peer queue info. */ + eth_hairpin_queue_peer_bind_t hairpin_queue_peer_bind; + /**< Set up the connection between the pair of hairpin queues. */ + eth_hairpin_queue_peer_unbind_t hairpin_queue_peer_unbind; + /**< Disconnect the hairpin queues of a pair from each other. */ }; /** @@ -1150,6 +1174,84 @@ typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev *ethdev, int rte_eth_dev_destroy(struct rte_eth_dev *ethdev, ethdev_uninit_t ethdev_uninit); +/** + * @internal + * Pass the current hairpin queue HW and/or SW information to the peer queue + * and fetch back the information of the peer queue. + * + * @param peer_port + * Peer port identifier of the Ethernet device. + * @param peer_queue + * Peer queue index of the port. + * @param cur_info + * Pointer to the current information structure. + * @param peer_info + * Pointer to the peer information, output. + * @param direction + * Direction to pass the information. + * true - pass TX queue information and get peer RX queue information + * false - pass RX queue information and get peer TX queue information + * + * @return + * Negative errno value on error, 0 on success. + */ +__rte_internal +int +rte_eth_hairpin_queue_peer_update(uint16_t peer_port, uint16_t peer_queue, + struct rte_hairpin_peer_info *cur_info, + struct rte_hairpin_peer_info *peer_info, + bool direction); + +/** + * @internal + * Configure current hairpin queue with the peer information fetched to create + * the connection (bind) with peer queue in the specified direction. + * This function might need to be called twice to fully create the connection. + * + * @param cur_port + * Current port identifier of the Ethernet device. + * @param cur_queue + * Current queue index of the port. + * @param peer_info + * Pointer to the peer information, input. + * @param direction + * Direction to create the connection. + * true - bind current TX queue to peer RX queue + * false - bind current RX queue to peer TX queue + * + * @return + * Negative errno value on error, 0 on success. + */ +__rte_internal +int +rte_eth_hairpin_queue_peer_bind(uint16_t cur_port, uint16_t cur_queue, + struct rte_hairpin_peer_info *peer_info, + bool direction); + +/** + * @internal + * Reset the current queue state and configuration to disconnect (unbind) it + * from the peer queue. + * This function might need to be called twice to disconnect each other. + * + * @param cur_port + * Current port identifier of the Ethernet device. + * @param cur_queue + * Current queue index of the port. + * @param direction + * Direction to create the connection. + * true - unbind current TX queue from peer RX queue + * false - unbind current RX queue from peer TX queue + * + * @return + * Negative errno value on error, 0 on success. + */ +__rte_internal +int +rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue, + bool direction); + + #ifdef __cplusplus } #endif diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map index 1019e28..0742733 100644 --- a/lib/librte_ethdev/rte_ethdev_version.map +++ b/lib/librte_ethdev/rte_ethdev_version.map @@ -251,6 +251,9 @@ INTERNAL { rte_eth_devargs_parse; rte_eth_dma_zone_free; rte_eth_dma_zone_reserve; + rte_eth_hairpin_queue_peer_bind; + rte_eth_hairpin_queue_peer_unbind; + rte_eth_hairpin_queue_peer_update; rte_eth_switch_domain_alloc; rte_eth_switch_domain_free; rte_flow_expand_rss; From patchwork Thu Oct 8 08:51:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bing Zhao X-Patchwork-Id: 79997 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A0117A04BC; Thu, 8 Oct 2020 10:53:25 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 53AED1BC74; Thu, 8 Oct 2020 10:52:18 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 90F701BC1A for ; Thu, 8 Oct 2020 10:52:11 +0200 (CEST) From: Bing Zhao To: thomas@monjalon.net, orika@nvidia.com, ferruh.yigit@intel.com, arybchenko@solarflare.com, mdr@ashroe.eu, nhorman@tuxdriver.com, bernard.iremonger@intel.com, beilei.xing@intel.com, wenzhuo.lu@intel.com Cc: dev@dpdk.org Date: Thu, 8 Oct 2020 16:51:37 +0800 Message-Id: <1602147098-9768-6-git-send-email-bingz@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1602147098-9768-1-git-send-email-bingz@nvidia.com> References: <1601511962-21532-1-git-send-email-bingz@nvidia.com> <1602147098-9768-1-git-send-email-bingz@nvidia.com> Subject: [dpdk-dev] [PATCH v2 5/6] app/testpmd: change hairpin queues setup X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" A new parameter `hairpin-mode` is introduced to the testpmd command line. Bitmask value is used to provide more flexible configuration. This parameter should be used when `hairpinq` is specified in the command line. Bit 0 in the LSB indicates the hairpin will use the loop mode. The previous port RX queue will be connected to the current port TX queue. Bit 1 in the LSB indicates the hairpin will use pair port mode. The even index port will be paired with the next odd index port. If the total number of probed port is odd, then the last one will be paired to itself. If this byte is zero, then each port will be paired to itself. Bit 0 takes a higher priority in the checking. Bit 4 in the second bytes indicate if the hairpin will use explicit TX flow mode. e.g. in the command line, "--hairpinq=2 --hairpin-mode=0x11" If not set, default value zero will be used and the behavior will try to get align with the previous single port mode. If the ports belong to different vendors' NICs, it is suggested to use the `self` hairpin mode only. Since hairpin configures the hardware resources, the port mask of packets forwarding engine will not be used here. Signed-off-by: Bing Zhao Acked-by: Ori Kam --- v2: move the hairpin bind/unbind into start/stop to support hot-plug and hot-unplug --- app/test-pmd/parameters.c | 15 ++++++ app/test-pmd/testpmd.c | 125 ++++++++++++++++++++++++++++++++++++++++++++-- app/test-pmd/testpmd.h | 2 + 3 files changed, 138 insertions(+), 4 deletions(-) diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index 1ead595..991029d 100644 --- a/app/test-pmd/parameters.c +++ b/app/test-pmd/parameters.c @@ -221,6 +221,9 @@ "enabled\n"); printf(" --record-core-cycles: enable measurement of CPU cycles.\n"); printf(" --record-burst-stats: enable display of RX and TX bursts.\n"); + printf(" --hairpin-mode=0xXX: bitmask set the hairpin port mode.\n " + " 0x10 - explicit tx rule, 0x02 - hairpin ports paired\n" + " 0x01 - hairpin ports loop, 0x00 - hairpin port self\n"); } #ifdef RTE_LIBRTE_CMDLINE @@ -644,6 +647,7 @@ { "rxd", 1, 0, 0 }, { "txd", 1, 0, 0 }, { "hairpinq", 1, 0, 0 }, + { "hairpin-mode", 1, 0, 0 }, { "burst", 1, 0, 0 }, { "mbcache", 1, 0, 0 }, { "txpt", 1, 0, 0 }, @@ -1111,6 +1115,17 @@ rte_exit(EXIT_FAILURE, "Either rx or tx queues should " "be non-zero\n"); } + if (!strcmp(lgopts[opt_idx].name, "hairpin-mode")) { + char *end = NULL; + unsigned int n; + + errno = 0; + n = strtoul(optarg, &end, 0); + if (errno != 0 || end == optarg) + rte_exit(EXIT_FAILURE, "hairpin mode invalid\n"); + else + hairpin_mode = (uint16_t)n; + } if (!strcmp(lgopts[opt_idx].name, "burst")) { n = atoi(optarg); if (n == 0) { diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index ccba71c..344de83 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -367,6 +367,9 @@ struct fwd_engine * fwd_engines[] = { /* Clear ptypes on port initialization. */ uint8_t clear_ptypes = true; +/* Hairpin ports configuration mode. */ +uint16_t hairpin_mode; + /* Pretty printing of ethdev events */ static const char * const eth_event_desc[] = { [RTE_ETH_EVENT_UNKNOWN] = "unknown", @@ -2345,7 +2348,7 @@ struct extmem_param { /* Configure the Rx and Tx hairpin queues for the selected port. */ static int -setup_hairpin_queues(portid_t pi) +setup_hairpin_queues(portid_t pi, portid_t p_pi, uint16_t cnt_pi) { queueid_t qi; struct rte_eth_hairpin_conf hairpin_conf = { @@ -2354,10 +2357,49 @@ struct extmem_param { int i; int diag; struct rte_port *port = &ports[pi]; + uint16_t peer_rx_port = pi; + uint16_t peer_tx_port = pi; + uint32_t manual = 1; + uint32_t tx_exp = hairpin_mode & 0x10; + + if (!(hairpin_mode & 0xf)) { + peer_rx_port = pi; + peer_tx_port = pi; + manual = 0; + } else if (hairpin_mode & 0x1) { + peer_tx_port = rte_eth_find_next_owned_by(pi + 1, + RTE_ETH_DEV_NO_OWNER); + if (peer_tx_port >= RTE_MAX_ETHPORTS) + peer_tx_port = rte_eth_find_next_owned_by(0, + RTE_ETH_DEV_NO_OWNER); + if (p_pi != RTE_MAX_ETHPORTS) { + peer_rx_port = p_pi; + } else { + uint16_t next_pi; + + /* Last port will be the peer RX port of the first. */ + RTE_ETH_FOREACH_DEV(next_pi) + peer_rx_port = next_pi; + } + manual = 1; + } else if (hairpin_mode & 0x2) { + if (cnt_pi & 0x1) { + peer_rx_port = p_pi; + } else { + peer_rx_port = rte_eth_find_next_owned_by(pi + 1, + RTE_ETH_DEV_NO_OWNER); + if (peer_rx_port >= RTE_MAX_ETHPORTS) + peer_rx_port = pi; + } + peer_tx_port = peer_rx_port; + manual = 1; + } for (qi = nb_txq, i = 0; qi < nb_hairpinq + nb_txq; qi++) { - hairpin_conf.peers[0].port = pi; + hairpin_conf.peers[0].port = peer_rx_port; hairpin_conf.peers[0].queue = i + nb_rxq; + hairpin_conf.manual_bind = !!manual; + hairpin_conf.tx_explicit = !!tx_exp; diag = rte_eth_tx_hairpin_queue_setup (pi, qi, nb_txd, &hairpin_conf); i++; @@ -2377,8 +2419,10 @@ struct extmem_param { return -1; } for (qi = nb_rxq, i = 0; qi < nb_hairpinq + nb_rxq; qi++) { - hairpin_conf.peers[0].port = pi; + hairpin_conf.peers[0].port = peer_tx_port; hairpin_conf.peers[0].queue = i + nb_txq; + hairpin_conf.manual_bind = !!manual; + hairpin_conf.tx_explicit = !!tx_exp; diag = rte_eth_rx_hairpin_queue_setup (pi, qi, nb_rxd, &hairpin_conf); i++; @@ -2405,6 +2449,12 @@ struct extmem_param { { int diag, need_check_link_status = -1; portid_t pi; + portid_t p_pi = RTE_MAX_ETHPORTS; + portid_t pl[RTE_MAX_ETHPORTS]; + portid_t peer_pl[RTE_MAX_ETHPORTS]; + uint16_t cnt_pi = 0; + uint16_t cfg_pi = 0; + int peer_pi; queueid_t qi; struct rte_port *port; struct rte_ether_addr mac_addr; @@ -2544,7 +2594,7 @@ struct extmem_param { return -1; } /* setup hairpin queues */ - if (setup_hairpin_queues(pi) != 0) + if (setup_hairpin_queues(pi, p_pi, cnt_pi) != 0) return -1; } configure_rxtx_dump_callbacks(verbose_level); @@ -2557,6 +2607,9 @@ struct extmem_param { pi); } + p_pi = pi; + cnt_pi++; + /* start port */ if (rte_eth_dev_start(pi) < 0) { printf("Fail to start port %d\n", pi); @@ -2581,6 +2634,8 @@ struct extmem_param { /* at least one port started, need checking link status */ need_check_link_status = 1; + + pl[cfg_pi++] = pi; } if (need_check_link_status == 1 && !no_link_check) @@ -2588,6 +2643,50 @@ struct extmem_param { else if (need_check_link_status == 0) printf("Please stop the ports first\n"); + if (hairpin_mode & 0xf) { + uint16_t i; + int j; + + /* bind all started hairpin ports */ + for (i = 0; i < cfg_pi; i++) { + pi = pl[i]; + /* bind current TX to all peer RX */ + peer_pi = rte_eth_hairpin_get_peer_ports(pi, + peer_pl, 1); + if (peer_pi < 0) + return peer_pi; + for (j = 0; j < peer_pi; j++) { + if (!port_is_started(peer_pl[j])) + continue; + diag = rte_eth_hairpin_bind(pi, peer_pl[j]); + if (diag < 0) { + printf("Error during binding " + "hairpin tx port %u to %u: %s", + pi, peer_pl[j], + rte_strerror(-diag)); + return -1; + } + } + /* bind all peer TX to current RX */ + peer_pi = rte_eth_hairpin_get_peer_ports(pi, + peer_pl, 0); + if (peer_pi < 0) + return peer_pi; + for (j = 0; j < peer_pi; j++) { + if (!port_is_started(peer_pl[j])) + continue; + diag = rte_eth_hairpin_bind(peer_pl[j], pi); + if (diag < 0) { + printf("Error during binding " + "hairpin tx port %u to %u: %s", + peer_pl[j], pi, + rte_strerror(-diag)); + return -1; + } + } + } + } + printf("Done\n"); return 0; } @@ -2598,6 +2697,8 @@ struct extmem_param { portid_t pi; struct rte_port *port; int need_check_link_status = 0; + portid_t peer_pl[RTE_MAX_ETHPORTS]; + int peer_pi; if (dcb_test) { dcb_test = 0; @@ -2628,6 +2729,22 @@ struct extmem_param { RTE_PORT_HANDLING) == 0) continue; + if (hairpin_mode & 0xf) { + int j; + + rte_eth_hairpin_unbind(pi, RTE_MAX_ETHPORTS); + /* unbind all peer TX from current RX */ + peer_pi = rte_eth_hairpin_get_peer_ports(pi, + peer_pl, 0); + if (peer_pi < 0) + continue; + for (j = 0; j < peer_pi; j++) { + if (!port_is_started(peer_pl[j])) + continue; + rte_eth_hairpin_unbind(peer_pl[j], pi); + } + } + rte_eth_dev_stop(pi); if (rte_atomic16_cmpset(&(port->port_status), diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index c7e7e41..29ede20 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -398,6 +398,8 @@ struct queue_stats_mappings { extern uint16_t stats_period; +extern uint16_t hairpin_mode; + #ifdef RTE_LIBRTE_LATENCY_STATS extern uint8_t latencystats_enabled; extern lcoreid_t latencystats_lcore_id; From patchwork Thu Oct 8 08:51:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bing Zhao X-Patchwork-Id: 79998 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 513B5A04BC; Thu, 8 Oct 2020 10:53:51 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 7ECA41BC8D; Thu, 8 Oct 2020 10:52:24 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 1E1671BC23 for ; Thu, 8 Oct 2020 10:52:15 +0200 (CEST) From: Bing Zhao To: thomas@monjalon.net, orika@nvidia.com, ferruh.yigit@intel.com, arybchenko@solarflare.com, mdr@ashroe.eu, nhorman@tuxdriver.com, bernard.iremonger@intel.com, beilei.xing@intel.com, wenzhuo.lu@intel.com Cc: dev@dpdk.org Date: Thu, 8 Oct 2020 16:51:38 +0800 Message-Id: <1602147098-9768-7-git-send-email-bingz@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1602147098-9768-1-git-send-email-bingz@nvidia.com> References: <1601511962-21532-1-git-send-email-bingz@nvidia.com> <1602147098-9768-1-git-send-email-bingz@nvidia.com> Subject: [dpdk-dev] [PATCH v2 6/6] doc: update for two ports hairpin mode X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" In the release notes, 2 ports hairpin mode feature is added. In rte flow part, one suggestion is added to mention that metadata could be used to connect the hairpin RX and TX flows if the hairpin is working in explicit TX flow rule mode. In the testpmd command line, the new parameter to set hairpin working mode is described. Signed-off-by: Bing Zhao Acked-by: Ori Kam --- doc/guides/prog_guide/rte_flow.rst | 3 +++ doc/guides/rel_notes/release_20_11.rst | 8 ++++++++ doc/guides/testpmd_app_ug/run_app.rst | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 119b128..bb54d67 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -2592,6 +2592,9 @@ set, unpredictable value will be seen depending on driver implementation. For loopback/hairpin packet, metadata set on Rx/Tx may or may not be propagated to the other path depending on HW capability. +In hairpin case with TX explicit flow mode, metadata could (not mandatory) be +used to connect the RX and TX flows if it can be propagated from RX to TX path. + .. _table_rte_flow_action_set_meta: .. table:: SET_META diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst index 0b2a370..05ceea0 100644 --- a/doc/guides/rel_notes/release_20_11.rst +++ b/doc/guides/rel_notes/release_20_11.rst @@ -109,6 +109,10 @@ New Features * Extern objects and functions can be plugged into the pipeline. * Transaction-oriented table updates. +* **Updated the ethdev library to support hairpin between two ports.** + + New APIs are introduced to support binding / unbinding 2 ports hairpin. + Hairpin TX part flow rules can be inserted explicitly. Removed Items ------------- @@ -240,6 +244,10 @@ ABI Changes * ``ethdev`` internal functions are marked with ``__rte_internal`` tag. + * ``struct rte_eth_hairpin_conf`` has two new members: + + * ``uint32_t tx_explicit:1;`` + * ``uint32_t manual_bind:1;`` Known Issues ------------ diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst index e2539f6..4e627c4 100644 --- a/doc/guides/testpmd_app_ug/run_app.rst +++ b/doc/guides/testpmd_app_ug/run_app.rst @@ -497,3 +497,11 @@ The command line options are: * ``--record-burst-stats`` Enable display of RX and TX burst stats. + +* ``--hairpin-mode=0xXX`` + + Set the hairpin port mode with bitmask, only valid when hairpin queues number is set. + bit 4 - explicit TX flow rule + bit 1 - two hairpin ports paired + bit 0 - two hairpin ports loop + The default value is 0. Hairpin will use single port mode and implicit TX flow mode.