From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM01-BN3-obe.outbound.protection.outlook.com (mail-bn3nam01on0087.outbound.protection.outlook.com [104.47.33.87]) by dpdk.org (Postfix) with ESMTP id 11BFA995C for ; Thu, 17 Aug 2017 18:12:27 +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=NdfxfTYslr90cEqnWMkRdauT1kvhWrvNffQ5zgzesuM=; b=a/LgD2Yf07SNkNaUfgQYC30GqsNfV1a25pwuwVAhErKw8J6eOqRCmatCnT0cR7uhJ7wzxEuT8wbFKlW9tldVQopBlwuyff/1lFFrl9oFd3PxEgCWUO2MctDsGE2ej3Kszq0LZIRu+2vPVn1eg1ak8rOEGNsjdJV/pedRN8v8Yt4= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Jerin.JacobKollanukkaran@cavium.com; Received: from jerin.domain.name (106.200.242.126) by CO2PR07MB2517.namprd07.prod.outlook.com (10.166.200.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.1341.21; Thu, 17 Aug 2017 16:12:21 +0000 From: Jerin Jacob To: dev@dpdk.org Cc: thomas@monjalon.net, bruce.richardson@intel.com, harry.van.haaren@intel.com, hemant.agrawal@nxp.com, gage.eads@intel.com, nipun.gupta@nxp.com, narender.vangati@intel.com, nikhil.rao@intel.com, pbhagavatula@caviumnetworks.com, jianbo.liu@linaro.org, rsanford@akamai.com, Jerin Jacob Date: Thu, 17 Aug 2017 21:41:04 +0530 Message-Id: <20170817161104.24293-2-jerin.jacob@caviumnetworks.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170817161104.24293-1-jerin.jacob@caviumnetworks.com> References: <20170817161104.24293-1-jerin.jacob@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [106.200.242.126] X-ClientProxiedBy: BMXPR01CA0035.INDPRD01.PROD.OUTLOOK.COM (10.174.214.21) To CO2PR07MB2517.namprd07.prod.outlook.com (10.166.200.151) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: acf83c90-af36-40c5-4c62-08d4e58ac008 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(2017030254152)(300000503095)(300135400095)(201703131423075)(201703031133081)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095); SRVR:CO2PR07MB2517; X-Microsoft-Exchange-Diagnostics: 1; CO2PR07MB2517; 3:Ogr/8X+eR+6xS2E2AMAsu4I/jMjcJv/0WwxNucd3Bz7whdxk5XsNoAKVVsu/i2JS2NciqXWUDqkgmEsPaNJZVqKLsaCfyYRfA8Pb3U35jfLrokSl5xjBHbaxQn7M1SUGPGVRIyQYreT9SCPhqNqAUK5NUsFcfqJCCApx8JBPFm95dnzo4VHdSpiuqlPagthq0jCWqOXtAixhvmLLhHX++RwYh2YDmMlaKWbAS3FuNyQYDNt6PbseiuBz+hVBDIa7; 25:oHA+NzEvc/NsqZbA33/CFn7XwVm5CbrTilK/eSmT9MKXkDm3+R6FRmrcXNq59P9nBJggwmjPUUXprwtiex9FASYRvvFGHjfhbQpZW5Kp8hdfB7S0M2SJDsuBtjtmS6ZwkezT2n5wRuEXqt36RYa/KWpJLiNexjEuMI8gUoFmhMxne/6jQ2yWfWmTte5mxFyWFhLkvQ92CzM8KUePO6Zb3NKlssJtrmOpKfjbbolDvigAkUYMzKsAH7r/HwFV4Exhk4M0hQ70y+FYEZhLLsvMS6f2PEkWqeDHBW2+8OO/weB4INas4GSL7oWi+nMFDcP29GLZaoPEDs+ZYYXd/VbNFg==; 31:Hsdlse0ZhSBCjWZ2hM8f3PRp2U2k9/vq6JonLaKfyp/SuYU2FMVhaqSJLonKpIaMF7jSi502o4/Os02yYPJsZVegmIwvYzMIHEGajtQST4Fx5sylYs05OocwYYswfCIEmzMOvrap8jVy6IVl9NXvOSI7uP2DgK/SxEXqeZ6YpCB+iCN7pHM63WyzPqeZp2C/d2SIlNwSNvDiMRwlXYA4UEyvMMyrGLsI8S/jJ0QQPgQ= X-MS-TrafficTypeDiagnostic: CO2PR07MB2517: X-Microsoft-Exchange-Diagnostics: 1; CO2PR07MB2517; 20:KVW6/Ps73Lw9/qP3X//BMJcATtA409p+irmqZ8Daa4FDF4MiNmACBcZArW+/aiSPFlFEKcXUMaSRfbbQZNhRXsycRtX1FzvhUvomRcjVXiAt0KFpJUsZWCmKxJdRjO6aJns/61F/JuVBTpAA7E+x4FIurGnbB3ZlZdOtxB5Gjf1BvjofRotEhZBE+pcWDG4U+BlzspGFVIhG2wqeV1nDgZQiVrpMz9tpRg2nxs+Sw4H5YWx70OBLeK/azYzoR9wnqrvSELxx8VnzqTrwcV0rONDE7kAeRIp6OEr3ASwlRITzwu9apBtVgmkPhUO5dbI8VObXh4ET/mp2Kbdn+KYaEWdeUi2nnqTKONYBmsv/V7WTwRcUQ+wj2ViOH2hlchq1ls1xx/BH/D1erN2E9W+9cfJF/NzIgU321Wqr5nsAAlrLB6gPcHN0I5sZkCiKvm/Jrfn4Z47SjyJRfmRksaKUw3cmL91s3IxsuWryDMmTRGVDwhFX9dAtLN7/5lfVv3kHG5U/jcuFq3+fRWkKtqNxUkeNjh0IIgcxnUaCCoE3n6ZHPhpoAwXqdMgSBtDl7Ul3XGF0yTkCWAXFpUZ29EtOlRTzIvZGEzlYSU48zoQbqXU=; 4:JhTzTYf6a1z8tNv5HZhPqoyGQCJ7dWkoyGwWGWcn5Jgkt+zfmSuAMUn2Y6TrgKK52Y3Pcb9NI7Y/NdeMgNknfyrAWCiufqyn9KK21SID35d9Pc0/9n+VYOkttbPwfmpeJ0Ghg22A3u2JfKsbOy4VBDiZ3+bI5ALsqs9y4gLTlUahSkMBVFlRbl5neeDQVYx2JN2O7yevrrhD7j6zxoeJ+5ghKlJyQjX0tS/bRX7J6qF90PAxjqIDAFpNwz7K+Gw7WwsiXleHKW+bqALbfZqndeEyiMW4D3s4J1ED4iqNXUo= X-Exchange-Antispam-Report-Test: UriScan:(17755550239193); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(93006095)(100000703101)(100105400095)(6041248)(20161123555025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123564025)(20161123562025)(20161123558100)(20161123560025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:CO2PR07MB2517; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:CO2PR07MB2517; X-Forefront-PRVS: 0402872DA1 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(7370300001)(6009001)(189002)(199003)(43544003)(6506006)(53936002)(2351001)(6512007)(6486002)(6666003)(110136004)(107886003)(106356001)(105586002)(2950100002)(42186005)(53416004)(42882006)(6916009)(5660300001)(69596002)(7416002)(48376002)(50466002)(101416001)(575784001)(33646002)(50986999)(76176999)(36756003)(189998001)(66066001)(478600001)(3846002)(6116002)(8676002)(81156014)(47776003)(81166006)(1076002)(25786009)(8656003)(7350300001)(2906002)(68736007)(5003940100001)(7736002)(305945005)(4326008)(72206003)(50226002)(2361001)(97736004)(5009440100003)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:CO2PR07MB2517; H:jerin.domain.name; 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: =?us-ascii?Q?1; CO2PR07MB2517; 23:WXNmwfYxLjlno37cHRjsg23IAoPMPCitI6ud6jWM2?= =?us-ascii?Q?TkIlEdUVostvbcRWKtylais5QuB5DKtr4bYHNzIGUsqRIe3YBZa52q3LXKfU?= =?us-ascii?Q?pwbKjrwSEOB8sRUUkfSmmHI3gMRxFY9aVN5XkVtB1KoLMThg8lSmoOkZwwat?= =?us-ascii?Q?aFoDS8pkG52WwG6rFyx2fVC2jAWnLSG4m33m/FKJfKUQtuNVFFA/Zo/wWTnJ?= =?us-ascii?Q?LLO4StjXkvZRZtFHq2ZaGKqwVenIKI+GQpv355eiZBWtAc6AGrXr8xHQ32ij?= =?us-ascii?Q?iTuj8pfOeVrzpDXfd9zpp0VqrBoE74BSudT1TgNMoUy/l0CK88k0mKdr3IxQ?= =?us-ascii?Q?r0Y1ZmRDcUYrxN7JTSiDSJGO6VOfjBGEjppoIl4eapHnFYoSFGGwF+vau6I9?= =?us-ascii?Q?7ITZDLqsSedufQMX2gycOCHI1lyTu2sUqJWhgysyxe2N5F03lCg05jTitvwE?= =?us-ascii?Q?dGzy8zZC3Iioh+LaF+X9EcpqkuZAnF/aWSgQGMsoV7HNA0ksluGVOSDF8VlP?= =?us-ascii?Q?ONQhjcr1X4yMh7oFR6YwudRY2IuswLMntfkUlcjp2A7h+LZGaATqGJtsVEtM?= =?us-ascii?Q?PwmYKLn7YxfMJnN6Cz0HDQOV622Twhop4z2VBQifcqo3pSIat3SpmT6GzZlm?= =?us-ascii?Q?QGTPZBbtr7STBJPJLokqxYoIFIJiiDQi1C+cGT0Tib3yOnrVU8eXNgViEAMb?= =?us-ascii?Q?cDSdziCVWSV79h78r9CexH84ZthkYTyaWZYiIe6HLZA5S3MJIxfHkuiV3+uN?= =?us-ascii?Q?MyDAhkkCOnRlIL2f/UdmsXEATvPcZ2f7r2NQQCvpKa4YwjXuvjp3Ev47/lFk?= =?us-ascii?Q?aKDHPnYcJHfESGkf3kyXsxKcBHgBf1ZuNoOCz3h9L+W8k/Ed3P7FS6soxiPS?= =?us-ascii?Q?HC/mI9DJH2tTvhWsFG5xwfVNobcKKkLlJ0+sWVRfyKh9KMlvOQGyY0+8kWW1?= =?us-ascii?Q?Nsnr2yy5z2YBbGmZ2NfJXpikmSLKPakzcfXhsczIrpv3Nl2IoR0+Rdfuo2JW?= =?us-ascii?Q?wGnkPeJEPGBRAgH5qTThcGlss4BYW2kM3j2qFrYOv3kW4oM/BSx6AZ/Q4jTj?= =?us-ascii?Q?UNlPyBOue8vxCy/zQ5LtxqKPHiI2n7N7hbVt1g4PCnwGuq114avIWWOtcwfU?= =?us-ascii?Q?7h52qfS91PKfS699imXrYXBayrCiUsfJurWB5Xmg0FGRPHIkQsoudTteZFXC?= =?us-ascii?Q?MlPAMg8h/ar+4IIZZ8unAMGJLntmlQGnI9ILP4hSfP6hzTW/5wpqiVDwiAak?= =?us-ascii?Q?1QZxCK85nRewd/uiWYZPXPZZKuVs5e2gLekBf/i5t3Rg67uSV2pcTr3lcsxH?= =?us-ascii?Q?eKJeyB4bQ1x4vCg1p3ZnnnCo/A21B1s6m/6wx17/hQMxPqfE20PKWAxPMX/6?= =?us-ascii?Q?p+xKQ=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; CO2PR07MB2517; 6:jy4RnRQRO0re6erZ+ne5qb+2ikLkQpnXwwRPQhOOYnayQ3lXCyXBfifm+Erovw56aUOqQ4hg+PJei2NISRc9/FnDzRrNkiuH//X/8ImittgGyBgQishQ6lSOyRE4lG8jt6nwxkwK0qN5DM4/fG/fu8V1CdKBqPoL4+VcrB7uvwT6S4FuEXOJCWIAp7AZq7oNlGoJmiJp4o/z9NOM9MjxdztN1jZgcFC70yOGkWLsCj336olkCCwfikLaUD8S/rpcj1rbIkRw/h0bWDgotcOGVNoCG7wJfzfJPkDAvldPAacuv2FcX+PwdDC/02CrC1OUcH65SxpAd2quLCs3PcjtKA==; 5:JWzDc4McS1jJF5jmJd5cW5sM80me3L/Ap2xBegdgMOjrAZ+/eogqq7Vpdl46c/b4VKMG93FEmJ44YY/Ayza2I/vOMpfbNZc01+xlT1Br73hNdMZ4gzw83AZU63NGFhS43P4GKHcW5UEiJX0CNAW7tg==; 24:dQebTfOZy7qBJYKbmP+5W9Kc/fFwxvLMLqF1mKU3FlfpuhSSMzJWt7msDoKJWgVYt10/y/vWcWSahpBpKctIlnwIByGnnNawIqKLVKL1dPU=; 7:vk7fBipnDuwsQ59+WKpvsN9GtnMVNz+7S+XbE7rh6R4mxa4rXS2gNPEd1c4u2u7U5mHaua4dU+RdG1AbvRnBhXkUpum7AHFyEcUr5swW2tr99czf9ChnPCtY3izwi7jfHoyux9LnzOUR+pc3J9/PbmswNKMBckkk26osY1QIoFqNnW8Yvbb66XrykJCAL3RQzLWyeOC+ZDx/pRjNBbXnlZSHrjmPmZ8xP9mk6Fb3sV8= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Aug 2017 16:12:21.1402 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO2PR07MB2517 Subject: [dpdk-dev] [RFC PATCH 1/1] eventtimer: introduce event timer wheel 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: Thu, 17 Aug 2017 16:12:28 -0000 Some of the NPU class of networking hardwares has timer hardware where the user can arm and cancel the event timer. On the expiry of the timeout time, the hardware will post the notification as an event to eventdev HW, Instead of calling a callback like CPU based timer scheme. It enables, high resolution (1us or so) timer management using internal or external clock domains, and offloading the timer housing keeping work from the worker lcores. This RFC attempts to abstract such NPU class of timer Hardware and introduce event timer wheel subsystem inside the eventdev as they are tightly coupled. This RFC introduces the functionality to create an event timer wheel. This allows an application to arm event timers, which shall enqueue an event to a specified event queue on expiry of a given interval. The event timer wheel uses an ops table to which the various event devices (e.g Cavium Octeontx, NXP dpaa2 and SW) register timer subsystem implementation specific ops to use. The RFC extends DPDK event based programming model where event can be of type timer, and expiry event will be notified through CPU over eventdev ports. Some of the use cases of event timer wheel are Beacon Timers, Generic SW Timeout, Wireless MAC Scheduling, 3G Frame Protocols, Packet Scheduling, Protocol Retransmission Timers, Supervision Timers. All these use cases require high resolution and low time drift. Signed-off-by: Jerin Jacob Signed-off-by: Pavan Nikhilesh --- doc/api/doxy-api-index.md | 3 +- lib/librte_eventdev/Makefile | 1 + lib/librte_eventdev/rte_event_timer_wheel.h | 493 ++++++++++++++++++++++++++++ lib/librte_eventdev/rte_eventdev.h | 4 +- 4 files changed, 498 insertions(+), 3 deletions(-) create mode 100644 lib/librte_eventdev/rte_event_timer_wheel.h diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md index 19e0d4f3d..6b8b6338a 100644 --- a/doc/api/doxy-api-index.md +++ b/doc/api/doxy-api-index.md @@ -55,7 +55,8 @@ The public API headers are grouped by topics: [KNI] (@ref rte_kni.h), [ixgbe] (@ref rte_pmd_ixgbe.h), [i40e] (@ref rte_pmd_i40e.h), - [crypto_scheduler] (@ref rte_cryptodev_scheduler.h) + [crypto_scheduler] (@ref rte_cryptodev_scheduler.h), + [event_timerwheel] (@ref rte_event_timer_wheel.h) - **memory**: [memseg] (@ref rte_memory.h), diff --git a/lib/librte_eventdev/Makefile b/lib/librte_eventdev/Makefile index 410578a14..ce1c128f5 100644 --- a/lib/librte_eventdev/Makefile +++ b/lib/librte_eventdev/Makefile @@ -50,6 +50,7 @@ SYMLINK-y-include += rte_eventdev_pmd.h SYMLINK-y-include += rte_eventdev_pmd_pci.h SYMLINK-y-include += rte_eventdev_pmd_vdev.h SYMLINK-y-include += rte_event_ring.h +SYMLINK-y-include += rte_event_timer_wheel.h # versioning export map EXPORT_MAP := rte_eventdev_version.map diff --git a/lib/librte_eventdev/rte_event_timer_wheel.h b/lib/librte_eventdev/rte_event_timer_wheel.h new file mode 100644 index 000000000..f568d2adf --- /dev/null +++ b/lib/librte_eventdev/rte_event_timer_wheel.h @@ -0,0 +1,493 @@ +/* + * BSD LICENSE + * + * Copyright 2017 Cavium, Inc. + * + * 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 Cavium, Inc 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_TIMER_WHEEL_H_ +#define _RTE_EVENT_TIMER_WHEEL_H_ + +/** + * @file + * + * RTE event timer wheel + * + * The abstract working model of an event timer wheel is as follows: + * + * timer_tick_ns + * + + * +-------+ | + * | | | + * +-------+ bkt 0 +----v---+ + * | | | | + * | +-------+ | + * +---+---+ +---+---+ +---+---+---+---+ + * | | | | | | | | | + * | bkt n | | bkt 1 |<-> t0| t1| t2| tn| + * | | | | | | | | | + * +---+---+ +---+---+ +---+---+---+---+ + * | Timer wheel | + * +---+---+ +---+---+ + * | | | | + * | bkt 4 | | bkt 2 |<--- Current bucket + * | | | | + * +---+---+ +---+---+ + * | +-------+ | + * | | | | + * +------+ bkt 3 +-------+ + * | | + * +-------+ + * + * - It has a virtual monotonically increasing 64-bit timer wheel clock based on + * *enum rte_event_timer_wheel_clk_src* clock source. The clock source could + * be a CPU clock, or a platform depended external clock. + * + * - Application creates a timer wheel instance with given clock source, + * the total number of event timers, resolution(expressed in ns) to traverse + * between the buckets. + * + * - Each timer wheel may have 0 to n buckets based on the configured + * max timeout(max_tmo_ns) and resolution(timer_tick_ns). On timer wheel + * start, the timer starts ticking at *timer_tick_ns* resolution. + * + * - Application arms an event timer to be expired at the number of + * *timer_tick_ns* from now. + * + * - Application can cancel the existing armed timer if required. + * + * - If not canceled by the application and the timer expires then the library + * injects the timer expiry event to the designated event queue. + * + * - The timer expiry event will be received through *rte_event_dequeue_burst* + * + * - Application frees the created timer wheel instance. + * + * Multiple timer wheels can be created with a varying level of resolution + * for various expiry use cases that run in parallel. + * + * Before using the timer wheel, the application has to create and configure + * an event device along with the event ports. Based on the event device + * capability it might require creating an additional event port to be used + * by the timer wheel. + * + * The application creates the event timer wheel using the + * ``rte_event_timer_wheel_create()``. The event device id is passed to this + * function, inside this function the event device capability is checked, + * and if an in-built port is absent the application uses the + * function to create a new producer port. + * + * The application may also use the function + * ``rte_event_timer_wheel_create_ext()`` to have granular control over producer + * port creation in a case where the in-built port is absent. + * + * After creating the timer wheel, the application has to start it + * using ``rte_event_timer_wheel_start()``. The buckets are traversed from + * 0 to n, the list per each bucket is processed, and the expired timer events + * are sent to the designated event queue. + * + * The application can arm one or more event timers using the + * ``rte_event_timer_arm_burst()``. The *timeout_ticks* represents the number + * of *timer_tick_ns* after which the timer has to expire. The timeout at + * which the timers expire can be grouped or be independent of each + * event timer instance. ``rte_event_timer_arm_tmo_tick_burst()`` address the + * former case and ``rte_event_timer_arm_burst()`` address the latter case. + * + * The application can cancel the timers from expiring using the + * ``rte_event_timer_cancel_burst()``. + * + * On the secondary process, ``rte_event_timer_wheel_lookup()`` can be used to + * get the timer wheel pointer from its id and use it to invoke fastpath + * operations such as arm and cancel. + * + * Some of the use cases of event timer wheel are Beacon Timers, + * Generic SW Timeout, Wireless MAC Scheduling, 3G Frame Protocols, + * Packet Scheduling, Protocol Retransmission Timers, Supervision Timers. + * All these use cases require high resolution and low time drift. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * Timer wheel clock source. + */ +enum rte_event_timer_wheel_clk_src { + RTE_EVENT_TIMER_WHEEL_CPU_CLK, + /**< Use CPU clock as the clock source. */ + RTE_EVENT_TIMER_WHEEL_EXT_CLK0, + /**< Platform dependent external clock source 0. */ + RTE_EVENT_TIMER_WHEEL_EXT_CLK1, + /**< Platform dependent external clock source 1. */ + RTE_EVENT_TIMER_WHEEL_EXT_CLK2, + /**< Platform dependent external clock source 2. */ + RTE_EVENT_TIMER_WHEEL_EXT_CLK3, + /**< Platform dependent external clock source 3. */ +}; + +#define RTE_EVENT_TIMER_WHEEL_F_ADJUST_RES (1ULL << 0) +/**< The event timer wheel implementation may have constraints on the wheel + * resolution(timer_tick_ns) and maximum timer expiry timeout(max_tmo_ns) + * based on the given event timer wheel or system. + * If this flag is set, implementation adjusts the wheel resolution and + * maximum timeout to the best possible configuration. + * On successful timer wheel creation, the application can get the configured + * resolution and max timeout with ``rte_event_timer_wheel_get_info()``. + * + * @see struct rte_event_timer_wheel_conf::timer_wheel_flags + */ +#define RTE_EVENT_TIMER_WHEEL_F_SP_PUT (1ULL << 1) +/**< ``rte_event_timer_arm_burst()`` API to be used in single producer mode. + * + * @see struct rte_event_timer_wheel_conf::timer_wheel_flags + */ + +/** + * Timer wheel configuration structure. + */ +struct rte_event_timer_wheel_conf { + uint8_t event_dev_id; + /**< Event device identifier.*/ + uint16_t timer_wheel_id; + /**< The event timer wheel identifier */ + enum rte_event_timer_wheel_clk_src clk_src; + /**< Clock source for timer wheel. */ + uint64_t timer_tick_ns; + /**< Timer wheel resolution in ns i.e interval between buckets.*/ + uint64_t max_tmo_ns; + /**< Maximum timer timeout(expiry) in ns.*/ + uint64_t nb_timers; + /**< Total number of timers per wheel.*/ + uint32_t timer_wheel_flags; + /**< Timer wheel config flags(RTE_EVENT_TIMER_WHEEL_F_*).*/ +}; + +struct rte_event_timer_wheel; + +/** + * Create an event timer wheel. + * + * This function must be invoked first before any other function in the API. + * + * @param conf + * The event timer wheel configuration structure. + * + * @return + * The pointer to the new allocated event timer wheel, on success. + * NULL on error with rte_errno set appropriately. + * Possible rte_errno values include: + * - ERANGE - timer_tick_ns is not in supported range. + */ +struct rte_event_timer_wheel * +rte_event_timer_wheel_create(const struct rte_event_timer_wheel_conf *conf); + +/** + * Callback function type for producer port creation. + */ +typedef void (*rte_event_timer_wheel_port_conf_cb)(uint16_t id, + uint8_t event_dev_id, uint8_t *event_port_id, + void *conf_arg); + +/** + * Create an timer wheel with supplied callback. + * + * This function can be used to have a more granular control over the timer + * wheel creation, If an inbuilt port is absent then the function uses the + * callback provided to create and get the port id to be used as producer port. + * + * + * @param[out] wheel + * A pointer to the event timer wheel structure pointer. + * @param conf + * The timer wheel configuration structure. + * @param conf_cb + * The port config callback function. + * @param conf_arg + * Opaque pointer to the callback function. + * + * @return + * The pointer to the new allocated event timer wheel, on success. + * NULL on error with rte_errno set appropriately. + * Possible rte_errno values include: + * - ERANGE - timer_tick_ns is not in supported range. + */ +struct rte_event_timer_wheel * +rte_event_timer_wheel_create_ext(const struct rte_event_timer_wheel_conf *conf, + rte_event_timer_wheel_port_conf_cb conf_cb, void *conf_arg); + +/** + * Timer wheel info structure. + */ +struct rte_event_timer_wheel_info { + uint64_t min_resoultion_ns; + /**< Minimum timer wheel resolution in ns.*/ + uint64_t max_tmo_ns; + /**< Maximum timer timeout(expiry) in ns. */ + struct rte_event_timer_wheel_conf wheel_conf; + /**< Configured timer wheel attributes. */ +}; + +/** + * Retrieve the contextual information of an event timer wheel. + * + * @param wheel + * A pointer to the event timer wheel structure. + * + * @param[out] wheel_info + * A pointer to a structure of type *rte_event_timer_wheel_info* to be + * filled with the contextual information of the wheel. + * + * @return + * - 0: Success, driver updates the contextual information of the + * timer wheel + * - <0: Error code returned by the driver info get function. + * + * @see RTE_EVENT_TIMER_WHEEL_F_ADJUST_RES, struct rte_event_timer_wheel_info + * + */ +int +rte_event_timer_wheel_get_info(const struct rte_event_timer_wheel *wheel, + struct rte_event_timer_wheel_info *wheel_info); + +/** + * Start an timer wheel. + * + * The wheel start step is the last one and consists of setting the timer + * wheel to start accepting the timers and schedules to event queues. + * + * On success, all basic functions exported by the API (timer arm, + * timer cancel and so on) can be invoked. + * + * @param wheel + * A pointer to the event timer wheel structure. + * + * @return + * - 0: Success, wheel started. + * - <0: Error code returned by the driver start function. + */ +int +rte_event_timer_wheel_start(const struct rte_event_timer_wheel *wheel); + +/** + * Stop an event timer wheel. + * + * The wheel can be restarted with a call to ``rte_event_timer_wheel_start()``. + * + * @param wheel + * A pointer to the event timer wheel structure. + * + * @return + * - 0: Success, wheel stop. + * - <0: Error code returned by the driver stop function. + */ +int +rte_event_timer_wheel_stop(const struct rte_event_timer_wheel *wheel); + +/** + * Free an event timer wheel. + * + * Destroy an event timer wheel, freeing all resources. + * + * Before invoking this function, the application must wait for all the armed + * timers to expire or cancel the outstanding armed timers. + * + * @param wheel + * A pointer to the event timer wheel structure. + * + * @return + * - 0 on successfully freed the event timer wheel resources. + * - <0 on failure to free an event timer wheel. + * - -EAGAIN if wheel is busy + */ +int +rte_event_timer_wheel_free(const struct rte_event_timer_wheel *wheel); + +/** + * Search an event timer wheel from its id. + * + * @param timer_wheel_id + * The event timer wheel identifier. + * + * @return + * The pointer to the event timer wheel matching the id, or NULL if not found. + * NULL on error with rte_errno set appropriately. + * Possible rte_errno values include: + * - ENOENT - required entry not available to return. + */ +struct rte_event_timer_wheel * +rte_event_timer_wheel_lookup(uint16_t timer_wheel_id); + +/** + * Event timer state. + */ +enum rte_event_timer_state { + RTE_EVENT_TIMER_NOT_ARMED = 0, + /**< Event timer is in not armed state.*/ + RTE_EVENT_TIMER_SUCCESS_ARM = 1, + /**< Event timer successfully armed.*/ + RTE_EVENT_TIMER_SUCCESS_CANCEL = 2, + /**< Event timer successfully canceled.*/ + RTE_EVENT_TIMER_ERROR = -1, + /**< Generic event timer error.*/ + RTE_EVENT_TIMER_ERROR_TOOEARLY = -2, + /**< Event timer timeout tick is too less to add to the wheel.*/ + RTE_EVENT_TIMER_ERROR_TOOLATE = -3, + /**< Event timer timeout tick is greater than the maximum timeout.*/ +}; + +/** + * The generic *rte_event_timer* structure to hold the event timer attributes + * for arm and cancel operations. + */ +RTE_STD_C11 +struct rte_event_timer { + struct rte_event ev; + /**< + * Expiry event attributes. On successful event timer timeout,following + * attributes will be used to inject the expiry event to eventdev. + * - event_queue_id: Targeted event queue id for expiry events. + * - event_priority: Event priority of the event expiry event in the + * event queue relative to other events. + * - sched_type: Scheduling type of the expiry event. + * - flow_id: Flow id of the expiry event. + * - op: RTE_EVENT_OP_NEW + * - event_type: RTE_EVENT_TYPE_TIMER + */ + enum rte_event_timer_state state; + /**< State of the event timer.*/ + uint64_t timeout_ticks; + /**< Expiry timer ticks expressed in number of *timer_ticks_ns* from + * now. + * @see struct rte_event_timer_wheel_info::wheel_conf::timer_tick_ns + */ + uint64_t impl_opaque[2]; + /**< Implementation specific opaque data. + * An event timer wheel implementation may use this field to hold + * implementation specific value to share between the arm and cancel + * operation. The application should not modify this field. + */ + uint8_t user_meta[]; + /**< Memory to store user specific metadata. + * The event timer wheel implementation should not modify this area. + */ +} __rte_cache_aligned; + +/** + * Arm a burst of event timers with separate expiration timeout tick for each + * event timer. + * + * Before calling this function, the application allocates + * ``struct rte_event_timer`` objects from mempool or huge page backed + * application buffers of interested size. On successful allocation, + * application updates the `struct rte_event_timer`` attributes such as + * expiry event attributes, timeout ticks from now. + * This function submits the event timer arm requests to the event timer wheel + * and on expiry, the events will be injected to designated event queue. + * + * @param wheel + * A pointer to the event timer wheel structure. + * @param tim + * Points to an array of objects of type *rte_event_timer* structure. + * @param nb_timers + * Number of event timers in the supplied array. + * + * @return + * The number of successfully armed event timers. The return value can be less + * than the value of the *nb_timers* parameter. If the return value is less + * than *nb_events*, the remaining event timers at the end of *tim* + * are not consumed, and the caller has to take care of them, and rte_errno + * is set accordingly. Possible errno values include: + * - -EINVAL Invalid timer wheel pointer, expiry event queue ID is invalid, + * or an expiry event's sched type doesn't match the capabilities of the + * destination event queue. + */ +int +rte_event_timer_arm_burst(const struct rte_event_timer_wheel *wheel, + struct rte_event_timer **tim, const uint16_t nb_timers); + +/** + * Arm a burst of event timers with same expiration timeout tick. + * + * Provides the same functionality as ``rte_event_timer_arm_burst()``, expect + * that application can use this API when the all the event timers have the + * same timeout expiration tick. This specialized function can provide the + * additional hint to the wheel implementation and optimize if possible. + * + * @param wheel + * A pointer to the event timer wheel structure. + * @param tim + * Points to an array of objects of type *rte_event_timer* structure. + * @param nb_timers + * Number of event timers in the supplied array. + * + * @return + * The number of successfully armed event timers. The return value can be less + * than the value of the *nb_timers* parameter. If the return value is less + * than *nb_events*, the remaining event timers at the end of *tim* + * are not consumed, and the caller has to take care of them, and rte_errno + * is set accordingly. Possible errno values include: + * - -EINVAL Invalid timer wheel pointer, expiry event queue ID is invalid, + * or an expiry event's sched type doesn't match the capabilities of the + * destination event queue. + */ +int +rte_event_timer_arm_tmo_tick_burst(const struct rte_event_timer_wheel *wheel, + struct rte_event_timer **tim, const uint64_t timeout_tick, + const uint16_t nb_timers); + + +/** + * Cancel a burst of event timer from being scheduled to the event device. + * + * @param wheel + * A pointer to the event timer wheel structure. + * @param tim + * Points to an array of objects of type *rte_event_timer* structure + * @param nb_timers + * Number of event timer instances in the supplied array. + * + * @return + * The number of successfully canceled event timers. The return value can be + * less than the value of the *nb_timers* parameter. If the return value is + * less than *nb_events*, the remaining event timers at the end of *tim* + * are not consumed, and the caller has to take care of them, and rte_errno + * is set accordingly. Possible errno values include: + * - -EINVAL Invalid timer wheel pointer + */ +int +rte_event_timer_cancel_burst(const struct rte_event_timer_wheel *wheel, + struct rte_event_timer **tim, const uint16_t nb_timers); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_EVENT_TIMER_WHEEL_H_ */ diff --git a/lib/librte_eventdev/rte_eventdev.h b/lib/librte_eventdev/rte_eventdev.h index 128bc5221..219ec5a3a 100644 --- a/lib/librte_eventdev/rte_eventdev.h +++ b/lib/librte_eventdev/rte_eventdev.h @@ -865,8 +865,8 @@ rte_event_dev_close(uint8_t dev_id); /**< The event generated from ethdev subsystem */ #define RTE_EVENT_TYPE_CRYPTODEV 0x1 /**< The event generated from crypodev subsystem */ -#define RTE_EVENT_TYPE_TIMERDEV 0x2 -/**< The event generated from timerdev subsystem */ +#define RTE_EVENT_TYPE_TIMER 0x2 +/**< The event generated from event timer wheel */ #define RTE_EVENT_TYPE_CPU 0x3 /**< The event generated from cpu for pipelining. * Application may use *sub_event_type* to further classify the event -- 2.14.1