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 B3E72A04BA; Wed, 7 Oct 2020 13:42:38 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 17F1F1B850; Wed, 7 Oct 2020 13:42:36 +0200 (CEST) Received: from nat-hk.nvidia.com (nat-hk.nvidia.com [203.18.50.4]) by dpdk.org (Postfix) with ESMTP id 56C561B74B for ; Wed, 7 Oct 2020 13:42:33 +0200 (CEST) Received: from HKMAIL104.nvidia.com (Not Verified[10.18.92.77]) by nat-hk.nvidia.com (using TLS: TLSv1.2, AES256-SHA) id ; Wed, 07 Oct 2020 19:42:32 +0800 Received: from HKMAIL102.nvidia.com (10.18.16.11) by HKMAIL104.nvidia.com (10.18.16.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 7 Oct 2020 11:42:27 +0000 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (104.47.56.171) by HKMAIL102.nvidia.com (10.18.16.11) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 7 Oct 2020 11:42:27 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dpu9Bq1gcBz9/EVtgcYfTE9beYvQdw7JS/jYgeGx54a5mpxvK83tbeIML8eF5DLseTMyVDA3iIp6LSA5bVWjIj+xPkKFZjrj7S3HFzd2qgTh0aoptjj5Ccv/m4IEFT6mYOp8KosQ486P+Dgx7CPIz59NCVb/ccsa1+9m7/6dlPGZSZP+Q87I3zwoiGbs7u7nN9taiQd/ysk0k2SDZT+4HvgydlhN5kI4koKOhbJDjSDpura/WOjCWEO7An0bmZ9EOGBuzYRuYai+sA9CawKbwaczQLyHsZgrRJ25jrb1cZiTjby5YqViFvDao6WYCT0I9WwAojyY2NLG8ANXKh/wdw== 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=WfMNyUIGrgBK7KdRDylNwZ7DfA8yjw7YexKh/KaPl9s=; b=SM/ZKeHAIX2Itvl3O+4JeHBDx/sLG98hWAHhIRiTN7JEGCmyMRfNqRLUrIw4EqAYwSd2H2kAKyt1NoxfZNZEm/zrnUx9D38KzG8kaLlZUMhmTr/bgq2/WALtnA6ZkOIcDajBXgjy/7lHtqDCe3F8wXI9IV559fuIY1UuRI1wKL/X52xxi0NGyZoCAB2ZkTmhqYmmW1nOoAuLVIKQ2JdHp+9EDyFmK5NndK0c0muGmHFKO5M64QawDHAO10G71N6vFnMVuYa15caE4XKAbtOIXjpANZzvKpOCZ7R9ON3Qi1ca3qU95qLWInDtD3IAGJN5F2T3zAAaq2rDeV9GttBaRQ== 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 MN2PR12MB4286.namprd12.prod.outlook.com (2603:10b6:208:199::22) by BL0PR12MB4852.namprd12.prod.outlook.com (2603:10b6:208:1ce::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3455.21; Wed, 7 Oct 2020 11:42:25 +0000 Received: from MN2PR12MB4286.namprd12.prod.outlook.com ([fe80::61fd:a36e:cf4f:2d3f]) by MN2PR12MB4286.namprd12.prod.outlook.com ([fe80::61fd:a36e:cf4f:2d3f%9]) with mapi id 15.20.3455.023; Wed, 7 Oct 2020 11:42:25 +0000 From: Ori Kam 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" Thread-Topic: [PATCH 1/4] ethdev: add hairpin bind and unbind APIs Thread-Index: AQHWl4mIK5rf2s6GGEWFCIE+TKZNUKmHI/vAgATlBACAAARWYA== Date: Wed, 7 Oct 2020 11:42:24 +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 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: [147.236.152.129] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 4b917471-8d05-4ced-9c97-08d86ab60fa8 x-ms-traffictypediagnostic: BL0PR12MB4852: 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: riTlUcabWMI38h9//R7fPfBW4SyT3D0AP4cJnEqiVtzJEolFvQiajgKV2gX9pHJN0qZ/oW9taUxjELoi3wdHmrvAb0TAz01BntfmNu0BSvG3jRuJFJUb1S1rCPk5eVAgtp3WN8LqmqWwsTF0dIcadTkBRKtbgFKFRGBdrXeJhYq9wD1npeqLiBeo0jGWzjAjIE5C4R/nX1UOZEcOGWXDskGtdd98hWPyZYbOIsU3t4XXay5MpmWge+/owMYO2s9NRTqdVsTuUZb4Q0UWJkUQM9XKLP/40JvY8Thvlf9mYxnqK9Zuzl08EV1O37Jvx16O0kPJEeij3MsvEAIU4P1aEg== x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:MN2PR12MB4286.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(366004)(346002)(136003)(39860400002)(376002)(396003)(2906002)(64756008)(66446008)(86362001)(55016002)(52536014)(76116006)(33656002)(66476007)(66556008)(66946007)(9686003)(83380400001)(4326008)(71200400001)(5660300002)(8936002)(30864003)(478600001)(8676002)(7696005)(110136005)(26005)(186003)(316002)(6506007)(53546011); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata: ndNNK897/zAvKv9fBYYa81tOSG4WgmJzwgCZyMCkt5yckU3ozy6TIlzNPGB/vovP7/HHqSuiDLJ2/631QAJAJ1Epgs1xmA6Waocz1VTxl7xGJHopMb3qERyzbuy0DteOk1Ml946DC00ASCka4cL1K0rEfh2JzOOURtyGXt1/r/3SOLvHZQBLoJHu/bFqistbwHrjqbsXLyDUs+Qp5OaS7mob+S6mktWyb47DL6XkGmNjms6ZKAOYSdNE3BZVDuPgRN8g1qkLy5DoJzU1mB+JojnNj168ru9BDACwublkng4fUdZJ9xZtXcv4YskQZh6sNiG7UBjkNkp4asC20j+bFWs/dplSFV1XL3PI3S24g+rPWJMlL4Bz+laEW0vnWs3fayc52r8KSOfzv18KTUn9phFYYYqwZeMIY18/9dA8CPxpVxIjHtdoO9BzEsjSx81odOq0MZCa76CPLQeT2U0Tx0mEcbB5d6ac29gc4/ugtuuS9jYZ/4pVmcx54GD0xC/4uwNES5tzeHADga2ZhW/5r8rT7bDCdcLrB3TsvFtIp74MnyY28mOZ557rtz28bdINiT6biCxIOvOUxFVi9NLLGMapHV0zd+yW9Q5ok4zigkBHSYUuxORGUKDC1UsL3Oh4TI6Hx6dJy2IW7a3TALnWuQ== 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: MN2PR12MB4286.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4b917471-8d05-4ced-9c97-08d86ab60fa8 X-MS-Exchange-CrossTenant-originalarrivaltime: 07 Oct 2020 11:42:24.9816 (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: aba3vjIIeEZyvuOPx9NB2b2wuFATfwD/b43uyeQiJAZlc9AyfydWkqqtsiJD4r4iFMPFNr16j8hcf2/CY6RNtg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL0PR12MB4852 X-OriginatorOrg: Nvidia.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1602070952; bh=WfMNyUIGrgBK7KdRDylNwZ7DfA8yjw7YexKh/KaPl9s=; 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=COlaveA8lQpVj0qf8H7jtASFauPap6gohm1ohldUuNB0V1yfzqv7UaWQLcU9Au5gH hePufjIUXWqSgZQn8ePpFE3OjZV1h8Zd31WV6jxNqrIJoIQklCPpSZp6iYM96J4DiL icEHCMO9PuETHNRMecAu0bUB10tsLRBiL2pQkMawqFOJ9mQsbOER/JERr9iFbLPMNt m+dpDbzdpMPivoGTyBYQzqNVj4/Wqhj+dZQ+700pZok2OhHFcFvwhbyFzHviwkfrsx 2l6km4N/zwQQvwlQY/Rv7ThWhvn70rZQrI2r8SmU5oRPRndBtw1Wub9fuHJY+cGc+I nh70pBIpAdodA== 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 Bing, > -----Original Message----- > From: Bing Zhao > Sent: Wednesday, October 7, 2020 2:22 PM > Subject: RE: [PATCH 1/4] ethdev: add hairpin bind and unbind APIs >=20 > Hi Ori, >=20 > > -----Original Message----- > > From: Ori Kam > > Sent: Sunday, October 4, 2020 5:20 PM > > Subject: RE: [PATCH 1/4] ethdev: add hairpin bind and unbind APIs > > > > Hi Bing, > > > > PSB, > > > > 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. > > > + */ > > > > I don't understand your comment. >=20 > I mean, in the following loops, if the application wants to bind one TX p= ort to all > the other RX ports, it would not be supported between different PMDs or > different NICs. Then the roll-back actions will be done and no hairpin po= rt peers > will work successfully. >=20 O.K. > > > > > + if (rx_port =3D=3D RTE_MAX_ETHPORTS) { > > > > 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? >=20 > Do you mean the checking in the RX ports loop below? At first, I intended= to > 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. >=20 I mean move the check to the tx pmd, if for some reason (peer device not st= arted) then it should fail. > > So either add a new function to get all peer ports from the tx port, > > or move this logic to the Target PMD. >=20 > There would be one more API to be introduced. To my understanding, it wou= ld > 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 I'm fine with moving the logic to the PMD as long as it can check the statu= s. which he can using the internal function right? > > > > > + 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) { > > > > 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. >=20 > 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 a= nd > return a failure then. >=20 Great we should also consider what happens in case of hot plug, In this case the hot plug port should be able to unbind himself from all ports. > > > > > + 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 >=20 > Thanks