From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 43C98A0542; Sat, 17 Dec 2022 10:21:41 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1650140695; Sat, 17 Dec 2022 10:21:39 +0100 (CET) Received: from mail.lysator.liu.se (mail.lysator.liu.se [130.236.254.3]) by mails.dpdk.org (Postfix) with ESMTP id 8F77A4068E for ; Sat, 17 Dec 2022 10:21:37 +0100 (CET) Received: from mail.lysator.liu.se (localhost [127.0.0.1]) by mail.lysator.liu.se (Postfix) with ESMTP id EF7603F61 for ; Sat, 17 Dec 2022 10:21:35 +0100 (CET) Received: by mail.lysator.liu.se (Postfix, from userid 1004) id EDD0639F8; Sat, 17 Dec 2022 10:21:35 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on hermod.lysator.liu.se X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=ALL_TRUSTED, AWL, NICE_REPLY_A autolearn=disabled version=3.4.6 X-Spam-Score: -1.5 Received: from [192.168.1.59] (h-62-63-215-114.A163.priv.bahnhof.se [62.63.215.114]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail.lysator.liu.se (Postfix) with ESMTPSA id 16B5B4139; Sat, 17 Dec 2022 10:21:32 +0100 (CET) Message-ID: <1cc2ff41-a7f0-555a-59b5-f68dae9d08ea@lysator.liu.se> Date: Sat, 17 Dec 2022 10:21:32 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2 Subject: Re: [PATCH] eventdev/timer: add API to get remaining ticks Content-Language: en-US To: Erik Gabriel Carrillo , jerinj@marvell.com Cc: s.v.naga.harish.k@intel.com, jay.jayatheerthan@intel.com, pbhagavatula@marvell.com, sthotton@marvell.com, dev@dpdk.org References: <20221216215615.2158238-1-erik.g.carrillo@intel.com> From: =?UTF-8?Q?Mattias_R=c3=b6nnblom?= In-Reply-To: <20221216215615.2158238-1-erik.g.carrillo@intel.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: ClamAV using ClamSMTP X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org On 2022-12-16 22:56, Erik Gabriel Carrillo wrote: > Introduce an event timer adapter API which allows users to determine how > many adapter ticks remain until an event timer fires. > > Signed-off-by: Erik Gabriel Carrillo > --- > app/test/test_event_timer_adapter.c | 68 ++++++++++++++++++++++++++ > lib/eventdev/event_timer_adapter_pmd.h | 7 +++ > lib/eventdev/rte_event_timer_adapter.c | 52 ++++++++++++++++++++ > lib/eventdev/rte_event_timer_adapter.h | 27 ++++++++++ > lib/eventdev/version.map | 3 ++ > 5 files changed, 157 insertions(+) > > diff --git a/app/test/test_event_timer_adapter.c b/app/test/test_event_timer_adapter.c > index 1a440dfd10..6529b14ff9 100644 > --- a/app/test/test_event_timer_adapter.c > +++ b/app/test/test_event_timer_adapter.c > @@ -1920,6 +1920,72 @@ adapter_create_max(void) > return TEST_SUCCESS; > } > > +static inline int > +test_timer_ticks_remaining(void) > +{ > + uint64_t ticks_remaining = UINT64_MAX; > + struct rte_event_timer *ev_tim; > + struct rte_event ev; > + int ret, i; > + const struct rte_event_timer tim = { > + .ev.op = RTE_EVENT_OP_NEW, > + .ev.queue_id = 0, > + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, > + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, > + .ev.event_type = RTE_EVENT_TYPE_TIMER, > + .state = RTE_EVENT_TIMER_NOT_ARMED, > + }; > + > + rte_mempool_get(eventdev_test_mempool, (void **)&ev_tim); > + *ev_tim = tim; > + ev_tim->ev.event_ptr = ev_tim; > +#define TEST_TICKS 5 > + ev_tim->timeout_ticks = CALC_TICKS(TEST_TICKS); > + > + /* Test that unarmed timer returns error */ > + TEST_ASSERT_FAIL(rte_event_timer_ticks_remaining_get(timdev, ev_tim, > + &ticks_remaining), > + "Didn't fail to get ticks for unarmed event timer"); > + > + TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, 1), 1, > + "Failed to arm timer with proper timeout."); > + TEST_ASSERT_EQUAL(ev_tim->state, RTE_EVENT_TIMER_ARMED, > + "Improper timer state set expected %d returned %d", > + RTE_EVENT_TIMER_ARMED, ev_tim->state); > + > + for (i = 0; i < TEST_TICKS; i++) { > + ret = rte_event_timer_ticks_remaining_get(timdev, ev_tim, > + &ticks_remaining); > + if (ret < 0) > + return TEST_FAILED; > + > + TEST_ASSERT_EQUAL((int)ticks_remaining, TEST_TICKS - i, > + "Expected %d ticks remaining, got %"PRIu64"", > + TEST_TICKS - i, ticks_remaining); > + > + rte_delay_ms(100); > + } > + > + rte_delay_ms(100); > + > + TEST_ASSERT_EQUAL(rte_event_dequeue_burst(evdev, 0, &ev, 1, 0), 1, > + "Armed timer failed to trigger."); > + TEST_ASSERT_EQUAL(ev_tim->state, RTE_EVENT_TIMER_NOT_ARMED, > + "Improper timer state set expected %d returned %d", > + RTE_EVENT_TIMER_NOT_ARMED, ev_tim->state); > + > + /* Test that timer that fired returns error */ > + TEST_ASSERT_FAIL(rte_event_timer_ticks_remaining_get(timdev, ev_tim, > + &ticks_remaining), > + "Didn't fail to get ticks for unarmed event timer"); > + > + rte_mempool_put(eventdev_test_mempool, (void *)ev_tim); > + > +#undef TEST_TICKS > + return TEST_SUCCESS; > +} > + > + > static struct unit_test_suite event_timer_adptr_functional_testsuite = { > .suite_name = "event timer functional test suite", > .setup = testsuite_setup, > @@ -1982,6 +2048,8 @@ static struct unit_test_suite event_timer_adptr_functional_testsuite = { > TEST_CASE_ST(timdev_setup_msec, timdev_teardown, > adapter_tick_resolution), > TEST_CASE(adapter_create_max), > + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, > + test_timer_ticks_remaining), > TEST_CASES_END() /**< NULL terminate unit test array */ > } > }; > diff --git a/lib/eventdev/event_timer_adapter_pmd.h b/lib/eventdev/event_timer_adapter_pmd.h > index 189017b5c1..c19ff3576a 100644 > --- a/lib/eventdev/event_timer_adapter_pmd.h > +++ b/lib/eventdev/event_timer_adapter_pmd.h > @@ -52,6 +52,11 @@ typedef int (*rte_event_timer_adapter_stats_get_t)( > typedef int (*rte_event_timer_adapter_stats_reset_t)( > const struct rte_event_timer_adapter *adapter); > /**< @internal Reset statistics for event timer adapter */ > +typedef int (*rte_event_timer_ticks_remaining_get_t)( > + const struct rte_event_timer_adapter *adapter, > + const struct rte_event_timer *evtim, > + uint64_t *ticks_remaining); > +/**< @internal Get remaining ticks for event timer */ > > /** > * @internal Structure containing the functions exported by an event timer > @@ -74,6 +79,8 @@ struct event_timer_adapter_ops { > /**< Arm event timers with same expiration time */ > rte_event_timer_cancel_burst_t cancel_burst; > /**< Cancel one or more event timers */ > + rte_event_timer_ticks_remaining_get_t ticks_remaining_get; > + /**< Get remaining ticks for event timer */ > }; > > /** > diff --git a/lib/eventdev/rte_event_timer_adapter.c b/lib/eventdev/rte_event_timer_adapter.c > index a0f14bf861..e2542e985c 100644 > --- a/lib/eventdev/rte_event_timer_adapter.c > +++ b/lib/eventdev/rte_event_timer_adapter.c > @@ -8,6 +8,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -458,6 +459,21 @@ rte_event_timer_adapter_stats_reset(struct rte_event_timer_adapter *adapter) > return adapter->ops->stats_reset(adapter); > } > > +int > +rte_event_timer_ticks_remaining_get( I think the general pattern is [<"sub-class">]_get_ rte_event_timer_get_remaining_ticks() > + const struct rte_event_timer_adapter *adapter, > + const struct rte_event_timer *evtim, > + uint64_t *ticks_remaining) > +{ > + ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL); > + FUNC_PTR_OR_ERR_RET(adapter->ops->ticks_remaining_get, -ENOTSUP); > + > + if (ticks_remaining == NULL) > + return -EINVAL; Why is this not an RTE_ASSERT()? Passing NULL is an API violation, likely due to a programming error. > + > + return adapter->ops->ticks_remaining_get(adapter, evtim, ticks_remaining); > +} > + > /* > * Software event timer adapter buffer helper functions > */ > @@ -1072,6 +1088,41 @@ swtim_stats_reset(const struct rte_event_timer_adapter *adapter) > return 0; > } > > +static int > +swtim_ticks_remaining_get(const struct rte_event_timer_adapter *adapter, > + const struct rte_event_timer *evtim, > + uint64_t *ticks_remaining) > +{ > + uint64_t nsecs_per_adapter_tick, opaque, cycles_remaining; > + enum rte_event_timer_state n_state; > + double nsecs_per_cycle; > + struct rte_timer *tim; > + uint64_t cur_cycles; > + > + /* Check that timer is armed */ > + n_state = __atomic_load_n(&evtim->state, __ATOMIC_ACQUIRE); > + if (n_state != RTE_EVENT_TIMER_ARMED) > + return -EINVAL; > + > + opaque = evtim->impl_opaque[0]; > + tim = (struct rte_timer *)(uintptr_t)opaque; > + > + cur_cycles = rte_get_timer_cycles(); > + if (cur_cycles > tim->expire) { > + *ticks_remaining = 0; > + return 0; > + } > + > + cycles_remaining = tim->expire - cur_cycles; > + nsecs_per_cycle = (double)NSECPERSEC / rte_get_timer_hz(); > + nsecs_per_adapter_tick = adapter->data->conf.timer_tick_ns; > + > + *ticks_remaining = (uint64_t)ceil((cycles_remaining * nsecs_per_cycle) / > + nsecs_per_adapter_tick); > + > + return 0; > +} > + > static uint16_t > __swtim_arm_burst(const struct rte_event_timer_adapter *adapter, > struct rte_event_timer **evtims, > @@ -1286,6 +1337,7 @@ static const struct event_timer_adapter_ops swtim_ops = { > .arm_burst = swtim_arm_burst, > .arm_tmo_tick_burst = swtim_arm_tmo_tick_burst, > .cancel_burst = swtim_cancel_burst, > + .ticks_remaining_get = swtim_ticks_remaining_get, > }; > > static int > diff --git a/lib/eventdev/rte_event_timer_adapter.h b/lib/eventdev/rte_event_timer_adapter.h > index cd10db19e4..b05d9b400d 100644 > --- a/lib/eventdev/rte_event_timer_adapter.h > +++ b/lib/eventdev/rte_event_timer_adapter.h > @@ -678,6 +678,33 @@ rte_event_timer_cancel_burst(const struct rte_event_timer_adapter *adapter, > return adapter->cancel_burst(adapter, evtims, nb_evtims); > } > > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice > + * > + * Get the number of ticks remaining until an event timer fires. > + * > + * @param adapter > + * A pointer to an event timer adapter structure > + * @param evtim > + * A pointer to an rte_event_timer structure > + * @param[out] ticks_remaining > + * Pointer to variable into which to write the number of ticks remaining > + * until the event timer fires > + * > + * @return > + * - 0: Success > + * - -EINVAL Invalid timer adapter identifier, ticks_remaining pointer is > + * NULL, or the event timer is not in the armed state > + * - -ENOTSUP The timer adapter implementation does not support this API. > + */ > +__rte_experimental > +int > +rte_event_timer_ticks_remaining_get( > + const struct rte_event_timer_adapter *adapter, > + const struct rte_event_timer *evtim, > + uint64_t *ticks_remaining); > + > #ifdef __cplusplus > } > #endif > diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map > index dd63ec6f68..2a46fd27dc 100644 > --- a/lib/eventdev/version.map > +++ b/lib/eventdev/version.map > @@ -118,6 +118,9 @@ EXPERIMENTAL { > rte_event_eth_tx_adapter_instance_get; > rte_event_eth_tx_adapter_queue_start; > rte_event_eth_tx_adapter_queue_stop; > + > + # added in 23.03 > + rte_event_timer_ticks_remaining_get; > }; > > INTERNAL {