From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM03-CO1-obe.outbound.protection.outlook.com (mail-co1nam03on0066.outbound.protection.outlook.com [104.47.40.66]) by dpdk.org (Postfix) with ESMTP id 418E6236 for ; Fri, 22 Sep 2017 08:08:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=I8bAxFHYeTte8kzD1kQnUtzUG9E4hJQb8FEu9AfNpx4=; b=CTL392cKMvNJoDtUbBhvPfzHQub0qJUDU8dXL9EOSqOPPOWw0l3ryBU9nkMvc9EJQWZ4kIATz6gAEPIz75uPGn3iUsE0eoHuevpxUaqffBV1tEONE1Bqm3yoOJ3TeMRZ3MP2R62P9PUitoA0Wih75WiBIG028feBPMJayR+VcjA= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Santosh.Shukla@cavium.com; Received: from [192.168.0.105] (103.76.56.167) by MWHPR07MB3104.namprd07.prod.outlook.com (10.172.95.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.77.7; Fri, 22 Sep 2017 06:08:38 +0000 To: Nikhil Rao , jerin.jacob@caviumnetworks.com, bruce.richardson@intel.com References: <1506028634-22998-1-git-send-email-nikhil.rao@intel.com> <1506028634-22998-4-git-send-email-nikhil.rao@intel.com> Cc: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net, harry.van.haaren@intel.com, hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com, erik.g.carrillo@intel.com, abhinandan.gujjar@intel.com From: santosh Message-ID: <78c747fd-3134-98f4-67cd-7c59f1e7e301@caviumnetworks.com> Date: Fri, 22 Sep 2017 11:38:26 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 In-Reply-To: <1506028634-22998-4-git-send-email-nikhil.rao@intel.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Originating-IP: [103.76.56.167] X-ClientProxiedBy: SG2PR0601CA0006.apcprd06.prod.outlook.com (10.170.128.16) To MWHPR07MB3104.namprd07.prod.outlook.com (10.172.95.10) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 868fd2ba-124f-416c-294c-08d50180606a X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(2017030254152)(300000503095)(300135400095)(2017052603199)(201703131423075)(201703031133081)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095); SRVR:MWHPR07MB3104; X-Microsoft-Exchange-Diagnostics: 1; MWHPR07MB3104; 3:/srKbqHdZK6eglu9JV5NH5jZ66hdxdR1BKmJ4pcGQGBdTxlSsZOSS6Nx6Nx60xWjf7VqJ6bvYToJmMaDkIMpqV0PnQ7Gl/1GMlUCYFpV2hX8bZaIcW+7r/bOQvCz2i3PeQKVBkRp+UBspcFogQbiM4pGIyKX1ibEQSY70xOs5lDCTxsHKla+ZSjLYpAJkZUKCnZYc87JfowDYRUelGSASyRSKo4OxKiLTrh3b5fwqmncDioHe/ADQ6XWfMSixJas; 25:KcUk+w/sJnhpGj6T9bNvKM4mg5/rrzcDaPmQ+SHKjEvLygGd3HvoV8qrhXt/YXeKS+Cq+vl+WAbhZroaonq8nxAFw+HRRhqEv54wqKVhoDxthBP7GWmwMzcrsJnngq6RV6sZv+cc0tkVvogfUlcqxTIV/JWJqyarQ6X7rR1OxhsElUPm1CWPfOmLaSDlMrc9qCzZq/3QJXlihmSCR3SRzAmiEuefaVuHGe8FHV+NXjGr3wt4NZm/fvT/HM7EkzB+aPl/myLI2TUVs8XoFrLkhfJ+a8Xa++Rhpkw62390Q6MTQ1QM9mmPy9jr0Ba9+13W85SlxMH9TkjPQY1YNGU3xA==; 31:sVMSUYf0AMNlm0/V9OCxwv/K3arrYTgL4Yyhaq8qCtmPCuGSDYxvT4n4tNHkziz30fNpgnKP120G+PeFIKF7ThmyJ8J8WplUiUDwWwQpzcvXZbYPUOHuX/0Jw0Jqkfy8Ib+DwyVwCy6vmJ4E8qkOz7VoEZBvqWjiQKI+o9z2i8KEW9JaMbhm2r9stTLV+z4NJ2pYvXiMLS8dz++HqgENDeAp4YOKV2iyniSoJzAYtCw= X-MS-TrafficTypeDiagnostic: MWHPR07MB3104: X-Microsoft-Exchange-Diagnostics: 1; MWHPR07MB3104; 20:bwiL4M06WXTUe/8z186VZ17L8znWG7QTAoeu1D35hci5UVWPoilisS71lp92w7R2E+UOZU0W+LhFwKAynv3kDHQt7FzZepekiUteBQVmQiBpEbRA1pEj/YrfM/9Iwh/kUnBLjdC4JoB4DMwP3bZ6WoS7VmQh/ZuJwOJIjulh33sUwJkXPr1OjFmR0lyC63BFYWLCj3Dohd7DQ0R5chNd/6S4qj1fGrxYzPRK5ndsKj9Xj3XzmVbGfwiBiQ4EMxZQ4hJb9ZgF7eekXkK1bLNdXKlv4WOR6LxlWPFodzDqepL/iidLkWSxb61SSV8BWmSRHwlA8bi8NHUCx35xJBfEYcSE+iOtGtmGvm7CZK86BBZjbhJugCuGPyCQ0f6q3OsFFYnauiboCRep+CPf5nP1ClPqJQ30uJiqhJ5aTqDV+ibcJ0ZQUAnyf8NT9jM0NrCiJ5FAVEmaEmmy0Tws/7zNGhXdnG9KoYr9F4MRf9z1GCtwdxcoV9OTJB5QF/VJHQLrh+LdkO+Ok25QTVA3u647O0x/xemu5hUatvRE7kbYIOZSexTW0bQFtpRU9iCOguzmXakE5G/9XmUm2JZT/IUVm3PyXhrAs4t9N7zXLxL3eFM= X-Exchange-Antispam-Report-Test: UriScan:(131327999870524)(228905959029699); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(3002001)(10201501046)(93006095)(100000703101)(100105400095)(6041248)(20161123558100)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123564025)(20161123562025)(20161123555025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:MWHPR07MB3104; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:MWHPR07MB3104; X-Microsoft-Exchange-Diagnostics: 1; MWHPR07MB3104; 4:u4NAYIR7zDi5zPlAnz9JK4hg92wYd9rhp3Z8oSkZftwx4kKUkbH+UFW/x2zvlGtPwestP+Sdsea0OTWWN3ZaOuJCCGe7ooN+WjEBnvT4MutwcGcw01fk2hxowajTMRHZnqQ7bNyJfvKKc4YiHd+Jj/lMk7QIuD3xFAijYncPJ+jrHzSQiQjvIAdVE8SUrJvwtJyGzuPS5HvxbBH6WJHK1CqenAxI0x1JNhzCqBXgVv9FUTi1ZWK+ynvwoQZT7EkBXfE4kV7KxPHRvzvLEbNi8czCjOhnmR7sA+FbY6NH0IKwAGh50EGU5pqOZ+qlmDLPvRfOpidm5UeLZg/TRvJ33w== X-Forefront-PRVS: 0438F90F17 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(6049001)(376002)(346002)(24454002)(189002)(377454003)(199003)(64126003)(478600001)(72206003)(966005)(33646002)(101416001)(23746002)(117156002)(4326008)(189998001)(50466002)(316002)(16526017)(66066001)(65956001)(47776003)(65806001)(16576012)(83506001)(105586002)(106356001)(2906002)(229853002)(54356999)(50986999)(6246003)(58126008)(76176999)(25786009)(6666003)(1720100001)(7416002)(6486002)(86152003)(5660300001)(6306002)(6116002)(3846002)(230700001)(90366009)(305945005)(7736002)(31686004)(31696002)(81156014)(81166006)(8676002)(8936002)(65826007)(77096006)(575784001)(53936002)(42882006)(2950100002)(68736007)(36756003)(97736004)(8656003); DIR:OUT; SFP:1101; SCL:1; SRVR:MWHPR07MB3104; H:[192.168.0.105]; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?Windows-1252?Q?1; MWHPR07MB3104; 23:X+BM3Z4ru+xJTlz2U+Un+xmIuPNbl6L0nK5h3?= =?Windows-1252?Q?gv9n4BM32d4ViizOhUxVbX+fO3+GH0AX0XpI4FFhZwCxYlhJaMuPUqh6?= =?Windows-1252?Q?VL9Ur6TA5D7unrixInNVbo+Nc0NsE16b/Scxk3fT17I/HAbkTnaC9MQo?= =?Windows-1252?Q?rM/KPnYQHv3cDDkZ4mF0ahc5PWogwHqfZ1bmlrFPvvzHEiYzMYYMajiV?= =?Windows-1252?Q?6rG/RnlOE8txCZfG5mSgPvFMcQPlHg/Q2jftVyRJZNkm9kwko9uRf2n9?= =?Windows-1252?Q?1123ogvb2yq/I3kYH6DsokGefuXbrTFxGZTP4URMVO1oZ6u0Jz/usFLX?= =?Windows-1252?Q?BC9Dw8kRgW2hdKjFA28LjImjKFIPMpTclNBCRc4KOjbnA/avMEyANBnQ?= =?Windows-1252?Q?0WAeRc9Udx3ygYP4e8J4xvu3mjUSg274kikvTULwzbEhfyA/BZD1LHft?= =?Windows-1252?Q?CDKyUaQfULYLSGnhaHFwpSeuD7uKmnpay+aCI/IOITYuUmMTCuxig1iX?= =?Windows-1252?Q?wsZ9+dYN++qBtcBGpkVe0Mcv2F3Qt8ZiKiVz843ke6EVxnNct42CUTUw?= =?Windows-1252?Q?dZ1JOH6h41zvsPN4IZMa/q2EdvZwVhHiFcse/jhSCo8tp+x+mNXJxkKW?= =?Windows-1252?Q?gam/YUw7JRWzsDwbYXcGQ5v8MrvuT9UHr9C7TmcxYBCMpVPbejbirCU7?= =?Windows-1252?Q?WWcD49+C8Rrh6BnpjddWVm6Ml3T5wRf8Zk30O9QvNUy0BSzJfPAOlgEi?= =?Windows-1252?Q?PxA3FQ29qF/crOw9ROtkBLqI/u8B5wz1KSQIute9VELJmhDsJzCr8MUU?= =?Windows-1252?Q?VEuKPYO6lRnRldvk3Q7hGByUSjm34VqXcceDFUtNvELdSg5a1YKhzOdB?= =?Windows-1252?Q?Nob4hwlJ6hxffRFTbSlEw57A30tWXt4ngOEVIXUHgxVkylxKtaaYJaqK?= =?Windows-1252?Q?ClBr5foSKqfJfrSeikXWnKmZqW+X1LpW3zIZyAZU8yaZNVFY1xPK5brD?= =?Windows-1252?Q?W14Ho9feBWUl074pXC8n7ooXlMvtotHVi7SAnGdsUISl3O2WK8JqiqZk?= =?Windows-1252?Q?/AH3MWoh4ADph7Ovi7udkv9dmVJTvK0X55D0cDpZ1X/BxRgwrESkoQxl?= =?Windows-1252?Q?1WvN/OrRUp33XnidH02KB8PI7V7+bOXRT4MRI/5xahdZt9jqMIeyGUOn?= =?Windows-1252?Q?K2+jDMZhEc2zb7vLd8XIqJbJxIQxAucK4cIT/9BRedrqrFNLSS4LAjKR?= =?Windows-1252?Q?qIyE+8PDVZ7TAfeuo1ADLqR9obNSlUSaxdg1r/hc9j3TQ/p1pf0OI4Zi?= =?Windows-1252?Q?I8dO2aHAN9Q6TfdINij8buEMzQeeu7xN/B2bjG7mpYSJ0p311l/FYUyn?= =?Windows-1252?Q?fl1EOcL9GX3GFcnP0jVTrRhQzChl8+hyvhjtZWOysluMAUtZ9SJvgM6H?= =?Windows-1252?Q?b6TQoenuV5xzJcmxkkzxSGa3lEgI7VAyp2+aS1oQZpDY6h9LlQ4ZKe3Q?= =?Windows-1252?Q?kNwRoWMJO6CGJd8U4gm1NBTd9uiVwSyT7IJN6KgFuP2dLply0TRl0YnG?= =?Windows-1252?Q?MxGqU1CPFWC22ZjlCrtUJMn8yk+11FTcbH6V+eeff0cOZ/yBjUirUi+Z?= =?Windows-1252?Q?+WGSMIcFk3lSt09K1TQU1E=3D?= X-Microsoft-Exchange-Diagnostics: 1; MWHPR07MB3104; 6:YAdC5sRJfxfFZ6ebRE49FAtNQpI/GO/SHCTwGygg2QDh5IZQT+rNoSTTu2fXVSshd80VG7kJajFeK2/UEISdMjX3j2GwraENBHrg/jKQ7l7lX/keeFRQwmwRiMbj5KPU0fYwQl9XNHaY5fWNxRf0GN+Im1eMbVYQhjMgza0K+iiBgjjs2fumcYId2W/JPZ4HtQfeoxdDjyYkFnGxfXYJoY5LvgOvOJwA3j35t6ABE67is/VbbKja1aof4XKTLpa/6ySnZFOvc4eI8bbG5Fv1UQ68DcXAtCNFBQEhrYXrbPnri3Jdj5n1V/kT/3jqpWR1vXEQ7Kq7nNiOt/YDGt9MCg==; 5:4TjXBUe2GCZLAJdPRrhKOdGTYtKJ+RRDbm49cRdThqTh4WgqXnf2H9ISWRiQl8l2rhZsQFfuQ9NeV5/WTH3eNBJOCyvyo/0JpJ0Et9SVDc/IEQw5Kgcjl4Z7U7ryF6Q0u/x3SqddCRl0D8hFaDdeHQ==; 24:MmXScpuEI6Ov0OfDQpYuRKYnJjABQwE0lBeGRFctzqvJarrEXftSdQVfLDChGraVgLm0YMNkbPHEaO1YX3hP4wpSPQFwN8tVL9w/o13tPSc=; 7:VtGTO4Ru6l2K9yaWr//iE4jX3XJaRlJOBINvY0YC+66mQBTQWfKOLKRlTI8MutIB3Ud06A8lq/2IhjDwK/YA8z2ukQaqFUBp8h72eKP6Qqv8hNmDVfFGDBJvUyiGbZv0lKOh3jWCTHrV8TW8aXenEBIoQYukHJQ0A/sTbPAPswYD6NN8fxdT9QGXsIXehsjmCpAWMYrVHeDsLk6ao3Fz0k5Wa3Esk+WNbdDiv1lEVT8= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Sep 2017 06:08:38.9055 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR07MB3104 Subject: Re: [dpdk-dev] [PATCH v4 3/4] eventdev: Add eventdev ethernet Rx adapter 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: , X-List-Received-Date: Fri, 22 Sep 2017 06:08:48 -0000 On Friday 22 September 2017 02:47 AM, Nikhil Rao wrote: > Add common APIs for configuring packet transfer from ethernet Rx > queues to event devices across HW & SW packet transfer mechanisms. > A detailed description of the adapter is contained in the header's > comments. > > The adapter implementation uses eventdev PMDs to configure the packet > transfer if HW support is available and if not, it uses an EAL service > function that reads packets from ethernet Rx queues and injects these > as events into the event device. > > Signed-off-by: Nikhil Rao > Signed-off-by: Gage Eads > Signed-off-by: Abhinandan Gujjar > --- > lib/librte_eventdev/rte_event_eth_rx_adapter.h | 384 ++++++++ > lib/librte_eventdev/rte_event_eth_rx_adapter.c | 1238 ++++++++++++++++++++++++ > lib/Makefile | 2 +- > lib/librte_eventdev/Makefile | 2 + > lib/librte_eventdev/rte_eventdev_version.map | 11 +- > 5 files changed, 1635 insertions(+), 2 deletions(-) > create mode 100644 lib/librte_eventdev/rte_event_eth_rx_adapter.h > create mode 100644 lib/librte_eventdev/rte_event_eth_rx_adapter.c > > diff --git a/lib/librte_eventdev/rte_event_eth_rx_adapter.h b/lib/librte_eventdev/rte_event_eth_rx_adapter.h > new file mode 100644 > index 000000000..c3849ec31 > --- /dev/null > +++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.h > @@ -0,0 +1,384 @@ > +/* > + * Copyright(c) 2017 Intel Corporation. All rights reserved. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * > + * * Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * * Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in > + * the documentation and/or other materials provided with the > + * distribution. > + * * Neither the name of Intel Corporation nor the names of its > + * contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT > + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR > + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT > + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifndef _RTE_EVENT_ETH_RX_ADAPTER_ > +#define _RTE_EVENT_ETH_RX_ADAPTER_ > + > +/** > + * @file > + * > + * RTE Event Ethernet Rx Adapter > + * > + * An eventdev-based packet processing application enqueues/dequeues mbufs > + * to/from the event device. The application uses the adapter APIs to configure > + * the packet flow between the ethernet devices and event devices. Depending on > + * on the capabilties of the eventdev PMD, the adapter may use a EAL service > + * core function for packet transfer or use internal PMD functions to configure > + * the packet transfer between the ethernet device and the event device. > + * > + * The ethernet Rx event adapter's functions are: > + * - rte_event_eth_rx_adapter_create_ext() > + * - rte_event_eth_rx_adapter_create()/free() > + * - rte_event_eth_rx_adapter_queue_add()/del() > + * - rte_event_eth_rx_adapter_start()/stop() > + * - rte_event_eth_rx_adapter_stats_get()/reset() > + * > + * The applicaton creates an event to ethernet adapter using > + * rte_event_eth_rx_adapter_create_ext() or rte_event_eth_rx_adapter_create() > + * functions. > + * The adapter needs to know which ethernet rx queues to poll for mbufs as well > + * as event device parameters such as the event queue identifier, event > + * priority and scheduling type that the adapter should use when constructing > + * events. The rte_event_eth_rx_adapter_queue_add() function is provided for > + * this purpose. > + * The servicing weight parameter in the rte_event_eth_rx_adapter_queue_conf > + * is applicable when the Rx adapter uses a service core function and is > + * intended to provide application control of the polling frequency of ethernet > + * device receive queues, for example, the application may want to poll higher > + * priority queues with a higher frequency but at the same time not starve > + * lower priority queues completely. If this parameter is zero and the receive > + * interrupt is enabled when configuring the device, the receive queue is > + * interrupt driven; else, the queue is assigned a servicing weight of one. > + * > + * If the adapter uses a rte_service function, then the application is also > + * required to assign a core to the service function and control the service > + * core using the rte_service APIs. The rte_event_eth_rx_adapter_service_id_get > + * function can be used to retrieve the service function ID of the adapter in > + * this case. > + * > + * Note: Interrupt driven receive queues are currentely unimplemented. > + */ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#include > +#include > + > +#include "rte_eventdev.h" > + > +#define RTE_MAX_EVENT_ETH_RX_ADAPTER_INSTANCE 32 > + > +/* struct rte_event_eth_rx_adapter_queue_conf flags definitions */ > +#define RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID 0x1 > +/**< This flag indicates the flow identifier is valid > + * @see rte_event_eth_rx_adapter_queue_conf > + */ > + > +struct rte_event_eth_rx_adapter_conf { > + uint8_t event_port_id; > + /**< Event port identifier, the adapter enqueues mbuf events to this > + * port > + */ > + uint32_t max_nb_rx; > + /**< The adapter can return early if it has processed at least > + * max_nb_rx mbufs. This isn't treated as a requirement; batching may > + * cause the adapter to process more than max_nb_rx mbufs > + */ > +}; > + > +/** > + * Function type used for adapter configuration callback. The callback is > + * used to fill in members of the struct rte_event_eth_rx_adapter_conf, this > + * callback is invoked when creating a SW service for packet transfer from > + * ethdev queues to the event device. The SW service is created within the > + * rte_event_eth_rx_adapter_queue_add() function if packet required. > + * > + * @param id > + * Adapter identifier. > + * > + * @param dev_id > + * Event device identifier. > + * > + * @conf > + * Structure that needs to be populated by this callback. > + * > + * @arg > + * Argument to the callback. This is the same as the conf_arg passed to the > + * rte_event_eth_rx_adapter_create_ext() > + */ > +typedef int (*rx_adapter_conf_cb) (uint8_t id, uint8_t dev_id, > + struct rte_event_eth_rx_adapter_conf *conf, > + void *arg); > + > +/** Rx queue configuration structure */ > +struct rte_event_eth_rx_adapter_queue_conf { > + uint32_t rx_queue_flags; > + /**< Flags for handling received packets > + * @see RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID > + */ > + uint16_t servicing_weight; > + /**< Relative polling frequency of ethernet receive queue, if this > + * is set to zero, the Rx queue is interrupt driven (unless rx queue > + * interrupts are not enabled for the ethernet device) > + */ > + struct rte_event ev; > + /**< > + * The values from the following event fields will be used when > + * enqueuing mbuf events: > + * - event_queue_id: Targeted event queue ID for received packets. > + * - event_priority: Event priority of packets from this Rx queue in > + * the event queue relative to other events. > + * - sched_type: Scheduling type for packets from this Rx queue. > + * - flow_id: If the RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID bit > + * is set in rx_queue_flags, this flow_id is used for all > + * packets received from this queue. Otherwise the flow ID > + * is set to the RSS hash of the src and dst IPv4/6 > + * address. > + * > + * The event adapter sets ev.event_type to RTE_EVENT_TYPE_ETHDEV in the > + * enqueued event > + */ > +}; > + > +struct rte_event_eth_rx_adapter_stats { > + uint64_t rx_poll_count; > + /**< Receive queue poll count */ > + uint64_t rx_packets; > + /**< Received packet count */ > + uint64_t rx_enq_count; > + /**< Eventdev enqueue count */ > + uint64_t rx_enq_retry; > + /**< Eventdev enqueue retry count */ > + uint64_t rx_enq_start_ts; > + /**< Rx enqueue start timestamp */ > + uint64_t rx_enq_block_cycles; > + /**< Cycles for which the service is blocked by the event device, > + * i.e, the service fails to enqueue to the event device. > + */ > + uint64_t rx_enq_end_ts; > + /**< Latest timestamp at which the service is unblocked > + * by the event device. The start, end timestamps and > + * block cycles can be used to compute the percentage of > + * cycles the service is blocked by the event device. > + */ > +}; > + > +/** > + * Create a new ethernet Rx event adapter with the specified identifier. > + * > + * @param id > + * The identifier of the ethernet Rx event adapter. > + * > + * @dev_id > + * The identifier of the device to configure. > + * > + * @eth_port_id > + * The identifier of the ethernet device. > + * > + * @param conf_cb > + * Callback function that fills in members of a > + * struct rte_event_eth_rx_adapter_conf struct passed into > + * it. > + * > + * @param conf_arg > + * Argument that is passed to the conf_cb function. > + * > + * @return > + * - 0: Success > + * - <0: Error code on failure > + */ > +int rte_event_eth_rx_adapter_create_ext(uint8_t id, uint8_t dev_id, > + rx_adapter_conf_cb conf_cb, > + void *conf_arg); > + > +/** > + * Create a new ethernet Rx event adapter with the specified identifier. > + * This function uses an internal configuration function that creates an event > + * port. This default function reconfigures the event device with an > + * additional event port and setups up the event port using the port_config > + * parameter passed into this function. In case the application needs more > + * control in configuration of the service, it should use the > + * rte_event_eth_rx_adapter_create_ext() version. > + * > + * @param id > + * The identifier of the ethernet Rx event adapter. > + * > + * @dev_id > + * The identifier of the device to configure. > + * > + * @eth_port_id > + * The identifier of the ethernet device. > + * > + * @param conf_cb > + * Callback function that fills in members of a > + * struct rte_event_eth_rx_adapter_conf struct passed into > + * it. > + * > + * @param conf_arg > + * Argument of type *rte_event_port_conf* that is passed to the conf_cb > + * function. > + * > + * @return > + * - 0: Success > + * - <0: Error code on failure > + */ > +int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, > + struct rte_event_port_conf *port_config); > + > +/** > + * Free an event adapter > + * > + * @param id > + * Adapter identifier. > + * > + * @return > + * - 0: Success > + * - <0: Error code on failure, If the adapter still has Rx queues > + * added to it, the function returns -EBUSY. > + */ > +int rte_event_eth_rx_adapter_free(uint8_t id); > + > +/** > + * Add receive queue to an event adapter. After a queue has been > + * added to the event adapter, the result of the application calling > + * rte_eth_rx_burst(eth_dev_id, rx_queue_id, ..) is undefined. > + * > + * @param id > + * Adapter identifier. > + * > + * @param eth_dev_id > + * Port identifier of Ethernet device. > + * > + * @param rx_queue_id > + * Ethernet device receive queue index. > + * If rx_queue_id is -1, then all Rx queues configured for > + * the device are added. If the ethdev Rx queues can only be > + * connected to a single event queue then rx_queue_id is > + * required to be -1. > + * > + * @param conf > + * Additonal configuration structure of type *rte_event_eth_rx_adapte_conf* > + * > + * @see > + * @return > + * - 0: Success, Receive queue added correctly. > + * - <0: Error code on failure. > + */ > +int rte_event_eth_rx_adapter_queue_add(uint8_t id, > + uint8_t eth_dev_id, > + int32_t rx_queue_id, > + const struct rte_event_eth_rx_adapter_queue_conf *conf); > + > +/** > + * Delete receive queue from an event adapter. > + * > + * @param id > + * Adapter identifier. > + * > + * @param eth_dev_id > + * Port identifier of Ethernet device. > + * > + * @param rx_queue_id > + * Ethernet device receive queue index. > + * If rx_queue_id is -1, then all Rx queues configured for > + * the device are deleted. If the ethdev Rx queues can only be > + * connected to a single event queue then rx_queue_id is > + * required to be -1. > + * > + * @return > + * - 0: Success, Receive queue deleted correctly. > + * - <0: Error code on failure. > + */ > +int rte_event_eth_rx_adapter_queue_del(uint8_t id, uint8_t eth_dev_id, > + int32_t rx_queue_id); > + > +/** > + * Start ethernet Rx event adapter > + * > + * @param id > + * Adapter identifier. > + * > + * @return > + * - 0: Success, Adapter started correctly. > + * - <0: Error code on failure. > + */ > +int rte_event_eth_rx_adapter_start(uint8_t id); > + > +/** > + * Stop ethernet Rx event adapter > + * > + * @param id > + * Adapter identifier. > + * > + * @return > + * - 0: Success, Adapter started correctly. > + * - <0: Error code on failure. > + */ > +int rte_event_eth_rx_adapter_stop(uint8_t id); > + > +/** > + * Retrieve statistics for an adapter > + * > + * @param id > + * Adapter identifier. > + * > + * @param stats > + * A pointer to structure used to retrieve statistics for an adapter. > + * > + * @return > + * - 0: Success, retrieved successfully. > + * - <0: Error code on failure. > + */ > +int rte_event_eth_rx_adapter_stats_get(uint8_t id, > + struct rte_event_eth_rx_adapter_stats *stats); > + > +/** > + * Reset statistics for an adapter > + * > + * @param id > + * Adapter identifier. > + * > + * @return > + * - 0: Success, statistics reset successfully. > + * - <0: Error code on failure. > + */ > +int rte_event_eth_rx_adapter_stats_reset(uint8_t id); > + > +/** > + * Retrieve the service ID of an adapter. If the adapter doesn't use > + * a rte_service function, this function returns -ESRCH > + * > + * @param id > + * Adapter identifier. > + * > + * @return > + * - 0: Success, statistics reset successfully. > + * - <0: Error code on failure, if the adapter doesn't use a rte_service > + * function, this function returns -ESRCH. > + */ > +int rte_event_eth_rx_adapter_service_id_get(uint8_t id, uint32_t *service_id); > + In general api comment: Fix missing param definition like *service_id* above and pl. remove other unnecessary params description from api above. > +#ifdef __cplusplus > +} > +#endif > +#endif /* _RTE_EVENT_ETH_RX_ADAPTER_ */ > diff --git a/lib/librte_eventdev/rte_event_eth_rx_adapter.c b/lib/librte_eventdev/rte_event_eth_rx_adapter.c > new file mode 100644 > index 000000000..d5b655dae > --- /dev/null > +++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.c > @@ -0,0 +1,1238 @@ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "rte_eventdev.h" > +#include "rte_eventdev_pmd.h" > +#include "rte_event_eth_rx_adapter.h" > + > +#define BATCH_SIZE 32 > +#define BLOCK_CNT_THRESHOLD 10 > +#define ETH_EVENT_BUFFER_SIZE (4*BATCH_SIZE) > + > +#define ETH_RX_ADAPTER_SERVICE_NAME_LEN 32 > +#define ETH_RX_ADAPTER_MEM_NAME_LEN 32 > + > +/* > + * There is an instance of this struct per polled Rx queue added to the > + * adapter > + */ > +struct eth_rx_poll_entry { > + /* eth port to poll */ > + uint8_t eth_dev_id; > + /* eth rx queue to poll */ > + uint16_t eth_rx_qid; > +}; > + > +/* Instance per adapter */ > +struct rte_eth_event_enqueue_buffer { > + /* Count of events in this buffer */ > + uint16_t count; > + /* Array of events in this buffer */ > + struct rte_event events[ETH_EVENT_BUFFER_SIZE]; > +}; > + > +struct rte_event_eth_rx_adapter { > + /* event device identifier */ > + uint8_t eventdev_id; > + /* per ethernet device structure */ > + struct eth_device_info *eth_devices; > + /* malloc name */ > + char mem_name[ETH_RX_ADAPTER_MEM_NAME_LEN]; > + /* socket identifier cached from eventdev */ > + int socket_id; > + > + /* elements below are used by SW service */ > + > + /* event port identifier */ > + uint8_t event_port_id; > + /* per adapter EAL service */ > + uint32_t service_id; > + /* lock to serialize config updates with service function */ > + rte_spinlock_t rx_lock; > + /* max mbufs processed in any service function invocation */ > + uint32_t max_nb_rx; > + /* Receive queues that need to be polled */ > + struct eth_rx_poll_entry *eth_rx_poll; > + /* size of the eth_rx_poll array */ > + uint16_t num_rx_polled; > + /* Weighted round robin schedule */ > + uint32_t *wrr_sched; > + /* wrr_sched[] size */ > + uint32_t wrr_len; > + /* Next entry in wrr[] to begin polling */ > + uint32_t wrr_pos; > + /* Event burst buffer */ > + struct rte_eth_event_enqueue_buffer event_enqueue_buffer; > + /* per adapter stats */ > + struct rte_event_eth_rx_adapter_stats stats; > + /* Block count, counts upto BLOCK_CNT_THRESHOLD */ > + uint16_t enq_block_count; > + /* Block start ts */ > + uint64_t rx_enq_block_start_ts; > + /* Configuration callback for rte_service configuration */ > + rx_adapter_conf_cb conf_cb; > + /* Configuration callback argument */ > + void *conf_arg; > + /* Service initialization state */ > + uint8_t service_inited; > + /* Total count of Rx queues in adapter */ > + uint32_t nb_queues; > +} __rte_cache_aligned; > + > +/* Per eth device */ > +struct eth_device_info { > + struct rte_eth_dev *dev; > + struct eth_rx_queue_info *rx_queue; > + /* Set if ethdev->eventdev packet transfer uses a > + * hardware mechanism > + */ > + uint8_t internal_event_port; > + /* set if the adapter is processing rx queues for > + * this eth device and packet processing has been > + * started, allows for the code to know if the PMD > + * rx_adapter_stop callback needs to be invoked > + */ > + uint8_t dev_rx_started; > + /* if nb_dev_queues > 0, the start callback will > + * be invoked if not already invoked > + */ > + uint16_t nb_dev_queues; > +}; > + > +/* Per Rx queue */ > +struct eth_rx_queue_info { > + int queue_enabled; /* true if added */ > + uint16_t wt; /* polling weight */ > + uint8_t event_queue_id; /* Event queue to enqueue packets to */ > + uint8_t sched_type; /* sched type for events */ > + uint8_t priority; /* event priority */ > + uint32_t flow_id; /* app provided flow identifier */ > + uint32_t flow_id_mask; /* Set to ~0 if app provides flow id else 0 */ > +}; > + > +static struct rte_event_eth_rx_adapter **rte_event_eth_rx_adapter; > +static struct rte_event_port_conf > + create_port_conf[RTE_MAX_EVENT_ETH_RX_ADAPTER_INSTANCE]; > + > +static uint8_t default_rss_key[] = { > + 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, > + 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, > + 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, > + 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, > + 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, > +}; > +static uint8_t *rss_key_be; > + > +static inline int > +valid_id(uint8_t id) > +{ > + return id < RTE_MAX_EVENT_ETH_RX_ADAPTER_INSTANCE; > +} > + > +#define RTE_EVENT_ETH_RX_ADAPTER_ID_VALID_OR_ERR_RET(id, retval) do { \ > + if (!valid_id(id)) { \ > + RTE_EDEV_LOG_ERR("Invalid eth Rx adapter id = %d\n", id); \ > + return retval; \ > + } \ > +} while (0) > + Worth, moving this macro to rte_eventdev_pmd.h Or How about reusing existing one ie.. RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET? > +static inline int > +sw_rx_adapter_queue_count(struct rte_event_eth_rx_adapter *rx_adapter) > +{ > + return rx_adapter->num_rx_polled; > +} > + > +/* Greatest common divisor */ > +static uint16_t gcd_u16(uint16_t a, uint16_t b) > +{ > + uint16_t r = a % b; > + > + return r ? gcd_u16(b, r) : b; > +} > + > +/* Returns the next queue in the polling sequence > + * > + * http://kb.linuxvirtualserver.org/wiki/Weighted_Round-Robin_Scheduling > + */ > +static int > +wrr_next(struct rte_event_eth_rx_adapter *rx_adapter, > + unsigned int n, int *cw, > + struct eth_rx_poll_entry *eth_rx_poll, uint16_t max_wt, > + uint16_t gcd, int prev) > +{ > + int i = prev; > + uint16_t w; > + > + while (1) { > + uint16_t q; > + uint8_t d; > + > + i = (i + 1) % n; > + if (i == 0) { > + *cw = *cw - gcd; > + if (*cw <= 0) > + *cw = max_wt; > + } > + > + q = eth_rx_poll[i].eth_rx_qid; > + d = eth_rx_poll[i].eth_dev_id; > + w = rx_adapter->eth_devices[d].rx_queue[q].wt; > + > + if ((int)w >= *cw) > + return i; > + } > +} > + > +/* Precalculate WRR polling sequence for all queues in rx_adapter */ > +static int > +eth_poll_wrr_calc(struct rte_event_eth_rx_adapter *rx_adapter) > +{ > + uint8_t d; > + uint16_t q; > + unsigned int i; > + > + /* Initialize variables for calculaton of wrr schedule */ > + uint16_t max_wrr_pos = 0; > + unsigned int poll_q = 0; > + uint16_t max_wt = 0; > + uint16_t gcd = 0; > + > + struct eth_rx_poll_entry *rx_poll = NULL; > + uint32_t *rx_wrr = NULL; > + > + if (rx_adapter->num_rx_polled) { > + size_t len = RTE_ALIGN(rx_adapter->num_rx_polled * > + sizeof(*rx_adapter->eth_rx_poll), > + RTE_CACHE_LINE_SIZE); > + rx_poll = rte_zmalloc_socket(rx_adapter->mem_name, > + len, > + RTE_CACHE_LINE_SIZE, > + rx_adapter->socket_id); > + if (!rx_poll) > + return -ENOMEM; > + > + /* Generate array of all queues to poll, the size of this > + * array is poll_q > + */ > + for (d = 0; d < rte_eth_dev_count(); d++) { > + uint16_t nb_rx_queues; > + struct eth_device_info *dev_info = > + &rx_adapter->eth_devices[d]; > + nb_rx_queues = dev_info->dev->data->nb_rx_queues; > + if (!dev_info->rx_queue) > + continue; > + for (q = 0; q < nb_rx_queues; q++) { > + struct eth_rx_queue_info *queue_info = > + &dev_info->rx_queue[q]; > + if (!queue_info->queue_enabled) > + continue; > + > + uint16_t wt = queue_info->wt; > + rx_poll[poll_q].eth_dev_id = d; > + rx_poll[poll_q].eth_rx_qid = q; > + max_wrr_pos += wt; > + max_wt = RTE_MAX(max_wt, wt); > + gcd = (gcd) ? gcd_u16(gcd, wt) : wt; > + poll_q++; > + } > + } > + > + len = RTE_ALIGN(max_wrr_pos * sizeof(*rx_wrr), > + RTE_CACHE_LINE_SIZE); > + rx_wrr = rte_zmalloc_socket(rx_adapter->mem_name, > + len, > + RTE_CACHE_LINE_SIZE, > + rx_adapter->socket_id); > + if (!rx_wrr) { > + rte_free(rx_poll); > + return -ENOMEM; > + } > + > + /* Generate polling sequence based on weights */ > + int prev = -1; > + int cw = -1; > + for (i = 0; i < max_wrr_pos; i++) { > + rx_wrr[i] = wrr_next(rx_adapter, poll_q, &cw, > + rx_poll, max_wt, gcd, prev); > + prev = rx_wrr[i]; > + } > + } > + > + rte_free(rx_adapter->eth_rx_poll); > + rte_free(rx_adapter->wrr_sched); > + > + rx_adapter->eth_rx_poll = rx_poll; > + rx_adapter->wrr_sched = rx_wrr; > + rx_adapter->wrr_len = max_wrr_pos; > + > + return 0; > +} > + > +static inline void > +mtoip(struct rte_mbuf *m, struct ipv4_hdr **ipv4_hdr, > + struct ipv6_hdr **ipv6_hdr) > +{ mtoip(), imo is more of global api, likely other modules may use in future.. perhaps move to rte_io.h Or more correct place.. thought? Thanks.