From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4B2C3A04BA; Wed, 7 Oct 2020 13:21:53 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id EAC561B733; Wed, 7 Oct 2020 13:21:51 +0200 (CEST) Received: from hqnvemgate26.nvidia.com (hqnvemgate26.nvidia.com [216.228.121.65]) by dpdk.org (Postfix) with ESMTP id 55990A69 for ; Wed, 7 Oct 2020 13:21:49 +0200 (CEST) Received: from hqmail.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, AES256-SHA) id ; Wed, 07 Oct 2020 04:21:35 -0700 Received: from HQMAIL111.nvidia.com (172.20.187.18) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 7 Oct 2020 11:21:46 +0000 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (104.47.66.45) by HQMAIL111.nvidia.com (172.20.187.18) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 7 Oct 2020 11:21:46 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OyNlJQs9qx7RnmIgnDJ56NskJJ7sQ0cxmUccXVZ2EDBgTEdKGA3YVqldkAKizEen3lfSzpymMRl5girE3aPrsflXLas/kxQ1d+scojgSjIZtAbCZP6QQzsdQYHIGR65Nlh9gNdi7aQ0b5PUOEN++hrRseRh8wcxA/W03OMlZIG08fgQAjOkeXjYBvSHBQWZtv03DCauszC+17cNxApy90EAvLkdmysixA8YX+oA1J4+oX1rfVEriXhd8hU4LBs1b16j0aKcbFOZoExX/SwJJGzz8c8LOEMigjZGmhoPBf1hfrpkt2F3ETv3mZJape7fD0scyp9QV+1z4WeGgi9lESQ== 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-SenderADCheck; bh=SqnaSQzmzmYBtaMdfoiuR3otcyslFm4qxzGlOLjPUnw=; b=mHyYaCg+UqYNxt3LBWOPRkPRPnkC9FBPZjMAVJnILBRVEqDXVLknJDLI9soYp4xCwBW7ewg0K4S6cCdtHsire94tmLNhc71OSopFRh/0Fv2jx2TA1918zG9Y4mgrWw604lkmoz3lq71QzdCIt8m1KO/rZAtwcEMa+nMOI0m1aAWshL/u3d6WRlKv+CeermP49yI2DekefphM6MEsnbMRWIL9ZbgeL0AMJqtkDuKiD3nB88GKnJVItaiosBacdq8Rvs5gkMZ7kDGtj5QPF4GR+1NrZQdXixlGUwhiFMFN1C28mVnsq7WRjBT7tSSsvEeP+RM/DF6XH7DoTbWusvx+kQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none Received: from CY4PR1201MB0072.namprd12.prod.outlook.com (2603:10b6:910:1b::19) by CY4PR12MB1478.namprd12.prod.outlook.com (2603:10b6:910:10::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3455.23; Wed, 7 Oct 2020 11:21:45 +0000 Received: from CY4PR1201MB0072.namprd12.prod.outlook.com ([fe80::f1b2:c80a:e623:e613]) by CY4PR1201MB0072.namprd12.prod.outlook.com ([fe80::f1b2:c80a:e623:e613%11]) with mapi id 15.20.3433.045; Wed, 7 Oct 2020 11:21:45 +0000 From: Bing Zhao To: Ori Kam , NBU-Contact-Thomas Monjalon , "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" Thread-Topic: [PATCH 1/4] ethdev: add hairpin bind and unbind APIs Thread-Index: AQHWmi+PejQ2YgJHe0OdY6to9qSZoamL+1Cg Date: Wed, 7 Oct 2020 11:21:44 +0000 Message-ID: References: <1600012140-70151-1-git-send-email-bingz@nvidia.com> <1601511962-21532-1-git-send-email-bingz@nvidia.com> <1601511962-21532-2-git-send-email-bingz@nvidia.com> In-Reply-To: Accept-Language: en-US, zh-CN Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: nvidia.com; dkim=none (message not signed) header.d=none;nvidia.com; dmarc=none action=none header.from=nvidia.com; x-originating-ip: [154.18.172.130] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 2f1b8b9c-7a27-49fb-c886-08d86ab32c84 x-ms-traffictypediagnostic: CY4PR12MB1478: x-ld-processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:10000; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 2fPxJKfEIc5VNEj8C7hrdYmFeTEZMzvxe/e4PF1aRT0TqwD9OBHmRWycpIdyVezpF84s9vi9mU+0USqrtnq4c+bQL/L+JtZxJH4qjtGWlWt2k0FsWmAYaj6qhXj4mHU+hfiO6yYqICAsNhlHwmk9J1VjgVNw4aBeCrIv/Lm1vhlF/ezvJCrsQGM2UC/+Oa7SNuEmZ9qokzxC09uQrN3slb+8U1IXsAJAxylWks2G3jZKjLL2gE7B05kUe+hMA8LV05r498QKU1P75JcZVWdmMHr9FG0sho6i+e2kGzlxrllN0IXu1kCdyEwRM1b/Zx1oVr380704nutSK8wuA1ADJA== x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CY4PR1201MB0072.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(376002)(366004)(136003)(39860400002)(346002)(396003)(86362001)(33656002)(478600001)(71200400001)(30864003)(66556008)(66476007)(66946007)(64756008)(76116006)(66446008)(5660300002)(2906002)(52536014)(8676002)(8936002)(83380400001)(9686003)(4326008)(316002)(110136005)(55016002)(7696005)(6506007)(53546011)(186003)(26005); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata: I8YB45EjY0VxLYaj3fvHj5CLIU2bVeDQYNCqt4d852VvR9E0ESX9ya07cIwEJaeXKzNEL5Vkmh6P9slSPJqGiGfkz2nB2Sc2nOkBXbzq9oLIzbasavVv7uJrCcqYPtZnhbP+hy2M8IUvzGxZwR4rgVRo/nPHMLJKdxYU1mitOC4ID8RMoAwE+IHquO4gz1NIVAX/xzx4iYiGt2ARNvMEmbZ72OBiRnBO5749+GVuViTHhfGGarc4twH8+g5OoKroscSKp7RO5Cu7DPZr3kv04DJvF9EjOy4ZNiFnPAWO4fJ7h+Lj1wH0j3rHp8JWrjZ2wXCFozgmju6kI1he/l+VLQX3yOWhtV2aGI1bZe/bXScZgXkqvJZRSy3avAcegXXjIckFK940YI2ZhDcY/KE78rJSWRV28eMA9sxvrE57h/qFRpcveeDkDcaTODT1kGddrbkM5BN+0PFGtdhjx4TMH4uXZpW+95r9Eob9SNaQj8t2CVufJmPzM2CiwEKPXyLcfHEdc4HI5IudUo5iIQvChl5pxY+HtiK+Yldy1XK8SAZ16DeH74W0wwGtBxmALrEnMxBO+g2T7WILva3O5uk8z+y6pLdaCrPLCnTSlX0YjChfBPRQcWVDdPtGl+9+gW9c+OS+7h94p8K3z9ZCQYu4fw== Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CY4PR1201MB0072.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2f1b8b9c-7a27-49fb-c886-08d86ab32c84 X-MS-Exchange-CrossTenant-originalarrivaltime: 07 Oct 2020 11:21:44.9765 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: kjCeZv+AguThFhc3rjgRqmYwO9V++tjGUwAOqx5k9swC31FjzScEIK/rIShjyrNJZLaqfCsR8fqeP86cfNyTrA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR12MB1478 X-OriginatorOrg: Nvidia.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1602069696; bh=SqnaSQzmzmYBtaMdfoiuR3otcyslFm4qxzGlOLjPUnw=; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:From:To: CC:Subject:Thread-Topic:Thread-Index:Date:Message-ID:References: In-Reply-To:Accept-Language:Content-Language:X-MS-Has-Attach: X-MS-TNEF-Correlator:authentication-results:x-originating-ip: x-ms-publictraffictype:x-ms-office365-filtering-correlation-id: x-ms-traffictypediagnostic:x-ld-processed: x-ms-exchange-transport-forked:x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers:x-ms-exchange-senderadcheck: x-microsoft-antispam:x-microsoft-antispam-message-info: x-forefront-antispam-report:x-ms-exchange-antispam-messagedata: Content-Type:Content-Transfer-Encoding:MIME-Version: X-MS-Exchange-CrossTenant-AuthAs: X-MS-Exchange-CrossTenant-AuthSource: X-MS-Exchange-CrossTenant-Network-Message-Id: X-MS-Exchange-CrossTenant-originalarrivaltime: X-MS-Exchange-CrossTenant-fromentityheader: X-MS-Exchange-CrossTenant-id:X-MS-Exchange-CrossTenant-mailboxtype: X-MS-Exchange-CrossTenant-userprincipalname: X-MS-Exchange-Transport-CrossTenantHeadersStamped:X-OriginatorOrg; b=L16e5fOtpjoNFkqEmIkgaBQfB3epKsfOtm10u5bb0IvFqKos5PJFVOYoknOH0mRX4 DxShyFSJ3fk6mI16Dc9/2kdPQ5daGQ+6fR6cNZGF1F0crpYcEx8DiBin6TT1xAQmet Y9lkKYdykdAClLxThd16UEvx8srry+p/GUnebn35LW81qBX6pRzuqypj+wDSHVy/q2 3tHCBlx68FMb11GbTsCkROnHOMSdNGQr9rZK0or+PIuD0iEXRDSemME6leIglzVe8a VHCZ9iD9DwU3ktRwk5nAIcpwlzIVUGdfuq8HBr7cyuRTlKCKBpU/gAQ5xV5GvWjpBK rlOqiNqJBiCAw== Subject: Re: [dpdk-dev] [PATCH 1/4] 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" Hi Ori, > -----Original Message----- > From: Ori Kam > Sent: Sunday, October 4, 2020 5:20 PM > To: Bing Zhao ; NBU-Contact-Thomas Monjalon > ; 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 > Subject: RE: [PATCH 1/4] ethdev: add hairpin bind and unbind APIs >=20 > Hi Bing, >=20 > PSB, >=20 > Thanks, > Ori > > -----Original Message----- > > From: Bing Zhao > > Sent: Thursday, October 1, 2020 3:26 AM > > Cc: dev@dpdk.org > > Subject: [PATCH 1/4] ethdev: add hairpin bind and unbind APIs > > > > 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. > > > > Signed-off-by: Bing Zhao > > --- > > lib/librte_ethdev/rte_ethdev.c | 107 > > +++++++++++++++++++++++++++++++ > > 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, 212 insertions(+) > > > > diff --git a/lib/librte_ethdev/rte_ethdev.c > > b/lib/librte_ethdev/rte_ethdev.c index dfe5c1b..72f567b 100644 > > --- a/lib/librte_ethdev/rte_ethdev.c > > +++ b/lib/librte_ethdev/rte_ethdev.c > > @@ -2175,6 +2175,113 @@ rte_eth_tx_hairpin_queue_setup(uint16_t > > port_id, uint16_t tx_queue_id, > > return eth_err(port_id, ret); > > } > > > > +int > > +rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port) { > > + struct rte_eth_dev *dev; > > + struct rte_eth_dev *rdev; > > + uint16_t p; > > + uint16_t rp; > > + int ret =3D 0; > > + > > + RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -EINVAL); > > + dev =3D &rte_eth_devices[tx_port]; > > + if (!dev->data->dev_started) { > > + RTE_ETHDEV_LOG(ERR, "TX port %d is not started", > tx_port); > > + return -EBUSY; > > + } > > + > > + /* > > + * If the all the ports probed belong to two or more separate > NICs, it > > + * is recommended that each pair is bound independently but > not in the > > + * loop to bind all ports. > > + */ >=20 > I don't understand your comment. I mean, in the following loops, if the application wants to bind one TX por= t to all the other RX ports, it would not be supported between different PM= Ds or different NICs. Then the roll-back actions will be done and no hairpi= n port peers will work successfully. >=20 > > + if (rx_port =3D=3D RTE_MAX_ETHPORTS) { >=20 > I think maybe this should be done in the tx queue. Since if the bind > don't need some port why do we care if it is started? Do you mean the checking in the RX ports loop below? At first, I intended t= o make sure this API would be called only after all the ports are started. But yes, there is no need if some port is not being used. > So either add a new function to get all peer ports from the tx port, > or move this logic to the Target PMD. There would be one more API to be introduced. To my understanding, it would= be more appropriate if we add a new API here. But it would keep RTE simpler if we move such logic into the PMD. >=20 > > + RTE_ETH_FOREACH_DEV(p) { > > + rdev =3D &rte_eth_devices[p]; > > + if (!rdev->data->dev_started) { > > + RTE_ETHDEV_LOG(ERR, > > + "RX port %d is not started", p); > > + ret =3D -EBUSY; > > + goto unbind; > > + } > > + ret =3D (*dev->dev_ops->hairpin_bind)(dev, p); > > + if (ret) { > > + RTE_ETHDEV_LOG(ERR, "Failed to bind hairpin > > TX " > > + "%d to RX %d", tx_port, p); > > + goto unbind; > > + } > > + } > > + } else { > > + RTE_ETH_VALID_PORTID_OR_ERR_RET(rx_port, -EINVAL); > > + rdev =3D &rte_eth_devices[rx_port]; > > + if (!rdev->data->dev_started) { > > + RTE_ETHDEV_LOG(ERR, > > + "RX port %d is not started", rx_port); > > + return -EBUSY; > > + } > > + ret =3D (*dev->dev_ops->hairpin_bind)(dev, rx_port); > > + if (ret) > > + RTE_ETHDEV_LOG(ERR, "Failed to bind hairpin TX %d > " > > + "to RX %d", tx_port, rx_port); > > + } > > + > > + return ret; > > + > > +unbind: > > + /* Roll back the previous binding process. */ > > + RTE_ETH_FOREACH_DEV(rp) { > > + if (rp < p) > > + (*dev->dev_ops->hairpin_unbind)(dev, rp); > > + else > > + break; > > + } > > + return ret; > > +} > > + > > +int > > +rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port) { > > + struct rte_eth_dev *dev; > > + struct rte_eth_dev *rdev; > > + uint16_t p; > > + int ret =3D 0; > > + > > + RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -EINVAL); > > + dev =3D &rte_eth_devices[tx_port]; > > + if (!dev->data->dev_started) { > > + RTE_ETHDEV_LOG(ERR, "TX port %d is stopped", tx_port); > > + return -EBUSY; > > + } > > + > > + if (rx_port =3D=3D RTE_MAX_ETHPORTS) { > > + RTE_ETH_FOREACH_DEV(p) { > > + rdev =3D &rte_eth_devices[p]; > > + if (!rdev->data->dev_started) { >=20 > This condition should never be true. > First see my comment above about the list of devices, second port > should fail to stop if it is bounded. Thank, I will remove this check and make the logic the same as "bind" API. When stopping the second port, PMD will check if any peer port is bound and= return a failure then. >=20 > > + RTE_ETHDEV_LOG(ERR, "RX port %d is > > stopped", p); > > + ret =3D -EBUSY; > > + break; > > + } > > + ret =3D (*dev->dev_ops->hairpin_unbind)(dev, p); > > + if (ret) { > > + RTE_ETHDEV_LOG(ERR, "Failed to unbind > > hairpin " > > + "TX %d from RX %d", tx_port, p); > > + break; > > + } > > + } > > + } else { > > + RTE_ETH_VALID_PORTID_OR_ERR_RET(rx_port, -EINVAL); > > + rdev =3D &rte_eth_devices[rx_port]; > > + if (!rdev->data->dev_started) { > > + RTE_ETHDEV_LOG(ERR, "RX port %d is stopped", > > rx_port); > > + return -EBUSY; > > + } > > + ret =3D (*dev->dev_ops->hairpin_unbind)(dev, rx_port); > > + } > > + > > + 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 645a186..c3fb684 100644 > > --- a/lib/librte_ethdev/rte_ethdev.h > > +++ b/lib/librte_ethdev/rte_ethdev.h > > @@ -2133,6 +2133,57 @@ int rte_eth_tx_hairpin_queue_setup > > 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 04ac8e9..910433f 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; > > }; > > -- > > 2.5.5 Thanks