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 A2DE445921; Fri, 6 Sep 2024 22:52:32 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2E92C40B99; Fri, 6 Sep 2024 22:52:32 +0200 (CEST) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mails.dpdk.org (Postfix) with ESMTP id 6EC134028F for ; Fri, 6 Sep 2024 22:52:30 +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 01347FEC; Fri, 6 Sep 2024 13:52:57 -0700 (PDT) Received: from ampere-altra-2-1.usa.Arm.com (ampere-altra-2-1.usa.arm.com [10.118.91.158]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 7D5FE3F73B; Fri, 6 Sep 2024 13:52:29 -0700 (PDT) From: Doug Foster To: Thomas Monjalon , Honnappa Nagarahalli Cc: dev@dpdk.org, Doug Foster , Wathsala Vithanage Subject: [PATCH] rcu: refactor rcu register/unregister functions Date: Fri, 6 Sep 2024 20:52:19 +0000 Message-Id: <20240906205219.629266-1-doug.foster@arm.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 This simplifies the implementation of rte_rcu_qsbr_thread_register() and rte_rcu_thread_unregister() functions. The simplified implementation is easier to read. Signed-off-by: Doug Foster Reviewed-by: Honnappa Nagarahalli Reviewed-by: Wathsala Vithanage --- .mailmap | 1 + lib/rcu/rte_rcu_qsbr.c | 77 ++++++++++++------------------------------ 2 files changed, 23 insertions(+), 55 deletions(-) diff --git a/.mailmap b/.mailmap index f76037213d..63d0f4187a 100644 --- a/.mailmap +++ b/.mailmap @@ -360,6 +360,7 @@ Don Provan Don Wallwork Doug Dziggel Douglas Flint +Doug Foster Dr. David Alan Gilbert Drocula Lambda Dror Birkman diff --git a/lib/rcu/rte_rcu_qsbr.c b/lib/rcu/rte_rcu_qsbr.c index f08d974d07..40d7c566c8 100644 --- a/lib/rcu/rte_rcu_qsbr.c +++ b/lib/rcu/rte_rcu_qsbr.c @@ -81,8 +81,8 @@ rte_rcu_qsbr_init(struct rte_rcu_qsbr *v, uint32_t max_threads) int rte_rcu_qsbr_thread_register(struct rte_rcu_qsbr *v, unsigned int thread_id) { - unsigned int i, id, success; - uint64_t old_bmap, new_bmap; + unsigned int i, id; + uint64_t old_bmap; if (v == NULL || thread_id >= v->max_threads) { RCU_LOG(ERR, "Invalid input parameter"); @@ -97,31 +97,15 @@ rte_rcu_qsbr_thread_register(struct rte_rcu_qsbr *v, unsigned int thread_id) id = thread_id & __RTE_QSBR_THRID_MASK; i = thread_id >> __RTE_QSBR_THRID_INDEX_SHIFT; - /* Make sure that the counter for registered threads does not - * go out of sync. Hence, additional checks are required. - */ - /* Check if the thread is already registered */ - old_bmap = rte_atomic_load_explicit(__RTE_QSBR_THRID_ARRAY_ELM(v, i), - rte_memory_order_relaxed); - if (old_bmap & 1UL << id) - return 0; + /* Add the thread to the bitmap of registered threads */ + old_bmap = rte_atomic_fetch_or_explicit(__RTE_QSBR_THRID_ARRAY_ELM(v, i), + (1UL << id), rte_memory_order_release); - do { - new_bmap = old_bmap | (1UL << id); - success = rte_atomic_compare_exchange_strong_explicit( - __RTE_QSBR_THRID_ARRAY_ELM(v, i), - &old_bmap, new_bmap, - rte_memory_order_release, rte_memory_order_relaxed); - - if (success) - rte_atomic_fetch_add_explicit(&v->num_threads, - 1, rte_memory_order_relaxed); - else if (old_bmap & (1UL << id)) - /* Someone else registered this thread. - * Counter should not be incremented. - */ - return 0; - } while (success == 0); + /* Increment the number of threads registered only if the thread was not already + * registered + */ + if (!(old_bmap & (1UL << id))) + rte_atomic_fetch_add_explicit(&v->num_threads, 1, rte_memory_order_relaxed); return 0; } @@ -132,8 +116,8 @@ rte_rcu_qsbr_thread_register(struct rte_rcu_qsbr *v, unsigned int thread_id) int rte_rcu_qsbr_thread_unregister(struct rte_rcu_qsbr *v, unsigned int thread_id) { - unsigned int i, id, success; - uint64_t old_bmap, new_bmap; + unsigned int i, id; + uint64_t old_bmap; if (v == NULL || thread_id >= v->max_threads) { RCU_LOG(ERR, "Invalid input parameter"); @@ -148,35 +132,18 @@ rte_rcu_qsbr_thread_unregister(struct rte_rcu_qsbr *v, unsigned int thread_id) id = thread_id & __RTE_QSBR_THRID_MASK; i = thread_id >> __RTE_QSBR_THRID_INDEX_SHIFT; - /* Make sure that the counter for registered threads does not - * go out of sync. Hence, additional checks are required. + /* Make sure any loads of the shared data structure are + * completed before removal of the thread from the bitmap of + * reporting threads. */ - /* Check if the thread is already unregistered */ - old_bmap = rte_atomic_load_explicit(__RTE_QSBR_THRID_ARRAY_ELM(v, i), - rte_memory_order_relaxed); - if (!(old_bmap & (1UL << id))) - return 0; + old_bmap = rte_atomic_fetch_and_explicit(__RTE_QSBR_THRID_ARRAY_ELM(v, i), + ~(1UL << id), rte_memory_order_release); - do { - new_bmap = old_bmap & ~(1UL << id); - /* Make sure any loads of the shared data structure are - * completed before removal of the thread from the list of - * reporting threads. - */ - success = rte_atomic_compare_exchange_strong_explicit( - __RTE_QSBR_THRID_ARRAY_ELM(v, i), - &old_bmap, new_bmap, - rte_memory_order_release, rte_memory_order_relaxed); - - if (success) - rte_atomic_fetch_sub_explicit(&v->num_threads, - 1, rte_memory_order_relaxed); - else if (!(old_bmap & (1UL << id))) - /* Someone else unregistered this thread. - * Counter should not be incremented. - */ - return 0; - } while (success == 0); + /* Decrement the number of threads unregistered only if the thread was not already + * unregistered + */ + if (old_bmap & (1UL << id)) + rte_atomic_fetch_sub_explicit(&v->num_threads, 1, rte_memory_order_relaxed); return 0; } -- 2.34.1