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 20E78A0523; Thu, 2 Jul 2020 07:28:41 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 571E91D8F8; Thu, 2 Jul 2020 07:28:36 +0200 (CEST) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by dpdk.org (Postfix) with ESMTP id 37B251D8EC for ; Thu, 2 Jul 2020 07:28:35 +0200 (CEST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A715C1FB; Wed, 1 Jul 2020 22:28:34 -0700 (PDT) Received: from phil-VirtualBox.shanghai.arm.com (phil-VirtualBox.shanghai.arm.com [10.169.106.164]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 074A13F73C; Wed, 1 Jul 2020 22:28:31 -0700 (PDT) From: Phil Yang To: erik.g.carrillo@intel.com, dev@dpdk.org Cc: jerinj@marvell.com, Honnappa.Nagarahalli@arm.com, drc@linux.vnet.ibm.com, Ruifeng.Wang@arm.com, Dharmik.Thakkar@arm.com, nd@arm.com Date: Thu, 2 Jul 2020 13:26:42 +0800 Message-Id: <1593667604-12029-2-git-send-email-phil.yang@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1593667604-12029-1-git-send-email-phil.yang@arm.com> References: <1591960798-24024-1-git-send-email-phil.yang@arm.com> <1593667604-12029-1-git-send-email-phil.yang@arm.com> Subject: [dpdk-dev] [PATCH v2 2/4] eventdev: use c11 atomics for lcore timer armed flag 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" The in_use flag is a per core variable which is not shared between lcores in the normal case and the access of this variable should be ordered on the same core. However, if non-EAL thread pick the highest lcore to insert timers into, there is the possibility of conflicts on this flag between threads. Then the atomic CAS operation is needed. Use the c11 atomic CAS instead of the generic rte_atomic operations to avoid the unnecessary barrier on aarch64. Signed-off-by: Phil Yang Reviewed-by: Dharmik Thakkar Reviewed-by: Ruifeng Wang --- v2: 1. Make the code comments more accurate. (Erik) 2. Define the in_use flag as an unsigned type. (Stephen) lib/librte_eventdev/rte_event_timer_adapter.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/librte_eventdev/rte_event_timer_adapter.c b/lib/librte_eventdev/rte_event_timer_adapter.c index a36d3d2..7cc334c 100644 --- a/lib/librte_eventdev/rte_event_timer_adapter.c +++ b/lib/librte_eventdev/rte_event_timer_adapter.c @@ -554,7 +554,7 @@ struct swtim { uint32_t timer_data_id; /* Track which cores have actually armed a timer */ struct { - rte_atomic16_t v; + uint16_t v; } __rte_cache_aligned in_use[RTE_MAX_LCORE]; /* Track which cores' timer lists should be polled */ unsigned int poll_lcores[RTE_MAX_LCORE]; @@ -606,7 +606,8 @@ swtim_callback(struct rte_timer *tim) "with immediate expiry value"); } - if (unlikely(rte_atomic16_test_and_set(&sw->in_use[lcore].v))) { + if (unlikely(sw->in_use[lcore].v == 0)) { + sw->in_use[lcore].v = 1; n_lcores = __atomic_fetch_add(&sw->n_poll_lcores, 1, __ATOMIC_RELAXED); __atomic_store_n(&sw->poll_lcores[n_lcores], lcore, @@ -834,7 +835,7 @@ swtim_init(struct rte_event_timer_adapter *adapter) /* Initialize the variables that track in-use timer lists */ for (i = 0; i < RTE_MAX_LCORE; i++) - rte_atomic16_init(&sw->in_use[i].v); + sw->in_use[i].v = 0; /* Initialize the timer subsystem and allocate timer data instance */ ret = rte_timer_subsystem_init(); @@ -1017,6 +1018,8 @@ __swtim_arm_burst(const struct rte_event_timer_adapter *adapter, struct rte_timer *tim, *tims[nb_evtims]; uint64_t cycles; int n_lcores; + /* Timer list for this lcore is not in use. */ + uint16_t exp_state = 0; #ifdef RTE_LIBRTE_EVENTDEV_DEBUG /* Check that the service is running. */ @@ -1035,8 +1038,12 @@ __swtim_arm_burst(const struct rte_event_timer_adapter *adapter, /* If this is the first time we're arming an event timer on this lcore, * mark this lcore as "in use"; this will cause the service * function to process the timer list that corresponds to this lcore. + * The atomic CAS operation can prevent the race condition on in_use + * flag between multiple non-EAL threads. */ - if (unlikely(rte_atomic16_test_and_set(&sw->in_use[lcore_id].v))) { + if (unlikely(__atomic_compare_exchange_n(&sw->in_use[lcore_id].v, + &exp_state, 1, 0, + __ATOMIC_RELAXED, __ATOMIC_RELAXED))) { EVTIM_LOG_DBG("Adding lcore id = %u to list of lcores to poll", lcore_id); n_lcores = __atomic_fetch_add(&sw->n_poll_lcores, 1, -- 2.7.4