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 7759AA04B5; Wed, 23 Sep 2020 04:20:39 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id F39AA1DBC9; Wed, 23 Sep 2020 04:20:26 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 6E7761DB61 for ; Wed, 23 Sep 2020 04:20:22 +0200 (CEST) IronPort-SDR: 4fqj5EdMHQvEanUycrk7eAseQFUoXO2tkxc6d8PTokuH5xyE5GVQddQeU2TfnxDUZfNmPsDEvT 1801fkivyBmg== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="158137483" X-IronPort-AV: E=Sophos;i="5.77,292,1596524400"; d="scan'208";a="158137483" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2020 19:20:20 -0700 IronPort-SDR: Vae5aCq4m+p9z4HBOlz14FgZVNXp36TzDOc2hZBsLasPlaWzmPiwxNUKItl69MODeQ5tbKxtEA f3tArgjN1PEw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,292,1596524400"; d="scan'208";a="322442475" Received: from skx-5gnr-sc12-4.sc.intel.com ([172.25.69.210]) by orsmga002.jf.intel.com with ESMTP; 22 Sep 2020 19:20:19 -0700 From: Nicolas Chautru To: dev@dpdk.org, akhil.goyal@nxp.com Cc: bruce.richardson@intel.com, rosen.xu@intel.com, dave.burley@accelercomm.com, aidan.goddard@accelercomm.com, ferruh.yigit@intel.com, tianjiao.liu@intel.com, Harry van Haaren Date: Tue, 22 Sep 2020 19:19:36 -0700 Message-Id: <1600827586-73414-2-git-send-email-nicolas.chautru@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1600827586-73414-1-git-send-email-nicolas.chautru@intel.com> References: <1597796731-57841-12-git-send-email-nicolas.chautru@intel.com> <1600827586-73414-1-git-send-email-nicolas.chautru@intel.com> Subject: [dpdk-dev] [PATCH v6 01/11] service: retrieve lcore active state 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" From: Harry van Haaren This commit adds a new experimental API which allows the user to retrieve the active state of an lcore. Knowing when the service lcore is completed its polling loop can be useful to applications to avoid race conditions when e.g. finalizing statistics. The service thread itself now has a variable to indicate if its thread is active. When zero the service thread has completed its service, and has returned from the service_runner_func() function. Suggested-by: Lukasz Wojciechowski Signed-off-by: Harry van Haaren Reviewed-by: Phil Yang Reviewed-by: Honnappa Nagarahalli --- lib/librte_eal/common/rte_service.c | 21 +++++++++++++++++++++ lib/librte_eal/include/rte_service.h | 22 +++++++++++++++++++++- lib/librte_eal/rte_eal_version.map | 1 + 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/librte_eal/common/rte_service.c b/lib/librte_eal/common/rte_service.c index 6a0e0ff..98565bb 100644 --- a/lib/librte_eal/common/rte_service.c +++ b/lib/librte_eal/common/rte_service.c @@ -65,6 +65,7 @@ struct core_state { /* map of services IDs are run on this core */ uint64_t service_mask; uint8_t runstate; /* running or stopped */ + uint8_t thread_active; /* indicates when thread is in service_run() */ uint8_t is_service_core; /* set if core is currently a service core */ uint8_t service_active_on_lcore[RTE_SERVICE_NUM_MAX]; uint64_t loops; @@ -457,6 +458,8 @@ struct core_state { const int lcore = rte_lcore_id(); struct core_state *cs = &lcore_states[lcore]; + __atomic_store_n(&cs->thread_active, 1, __ATOMIC_SEQ_CST); + /* runstate act as the guard variable. Use load-acquire * memory order here to synchronize with store-release * in runstate update functions. @@ -475,10 +478,28 @@ struct core_state { cs->loops++; } + /* Use SEQ CST memory ordering to avoid any re-ordering around + * this store, ensuring that once this store is visible, the service + * lcore thread really is done in service cores code. + */ + __atomic_store_n(&cs->thread_active, 0, __ATOMIC_SEQ_CST); return 0; } int32_t +rte_service_lcore_may_be_active(uint32_t lcore) +{ + if (lcore >= RTE_MAX_LCORE || !lcore_states[lcore].is_service_core) + return -EINVAL; + + /* Load thread_active using ACQUIRE to avoid instructions dependent on + * the result being re-ordered before this load completes. + */ + return __atomic_load_n(&lcore_states[lcore].thread_active, + __ATOMIC_ACQUIRE); +} + +int32_t rte_service_lcore_count(void) { int32_t count = 0; diff --git a/lib/librte_eal/include/rte_service.h b/lib/librte_eal/include/rte_service.h index e2d0a6d..ca9950d 100644 --- a/lib/librte_eal/include/rte_service.h +++ b/lib/librte_eal/include/rte_service.h @@ -249,7 +249,11 @@ int32_t rte_service_run_iter_on_app_lcore(uint32_t id, * Stop a service core. * * Stopping a core makes the core become idle, but remains assigned as a - * service core. + * service core. Note that the service lcore thread may not have returned from + * the service it is running when this API returns. + * + * The *rte_service_lcore_may_be_active* API can be used to check if the + * service lcore is * still active. * * @retval 0 Success * @retval -EINVAL Invalid *lcore_id* provided @@ -262,6 +266,22 @@ int32_t rte_service_run_iter_on_app_lcore(uint32_t id, int32_t rte_service_lcore_stop(uint32_t lcore_id); /** + * Reports if a service lcore is currently running. + * + * This function returns if the core has finished service cores code, and has + * returned to EAL control. If *rte_service_lcore_stop* has been called but + * the lcore has not returned to EAL yet, it might be required to wait and call + * this function again. The amount of time to wait before the core returns + * depends on the duration of the services being run. + * + * @retval 0 Service thread is not active, and lcore has been returned to EAL. + * @retval 1 Service thread is in the service core polling loop. + * @retval -EINVAL Invalid *lcore_id* provided. + */ +__rte_experimental +int32_t rte_service_lcore_may_be_active(uint32_t lcore_id); + +/** * Adds lcore to the list of service cores. * * This functions can be used at runtime in order to modify the service core diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index eba868e..c32461c 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -394,6 +394,7 @@ EXPERIMENTAL { rte_lcore_dump; rte_lcore_iterate; rte_mp_disable; + rte_service_lcore_may_be_active; rte_thread_register; rte_thread_unregister; }; -- 1.8.3.1