From patchwork Wed Jun 10 14:45:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 71196 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 51241A051F; Wed, 10 Jun 2020 16:45:44 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2E4961BFA6; Wed, 10 Jun 2020 16:45:44 +0200 (CEST) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) by dpdk.org (Postfix) with ESMTP id 803881BF80 for ; Wed, 10 Jun 2020 16:45:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1591800342; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5EAlW6ILiQzVmuiLcDTTl+fPkrLc0EXCeM2ZR7Z6wyE=; b=CJ1E6PkDwHuzQhsFdlnkeqi1P00HpyZwzAmoLuaB79+pT3HBqltX4qsNbTEoECt89xLQR/ 1CMWgBbSJM5F17Sy4kMAWwvph8ahakHQWsSjcCZeT6W0kvnrQ/8y/gfpuvpy3F7bn3Je33 k8KnKzZGibe34OKFCnvKoRC7yv+2sm4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-390-_xjMLS8XPqi6HVm0E_c0GQ-1; Wed, 10 Jun 2020 10:45:38 -0400 X-MC-Unique: _xjMLS8XPqi6HVm0E_c0GQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AF03B8014D4; Wed, 10 Jun 2020 14:45:36 +0000 (UTC) Received: from dmarchan.remote.csb (unknown [10.40.192.116]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0094360BF3; Wed, 10 Jun 2020 14:45:34 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Bruce Richardson , Harini Ramakrishnan , Omar Cardona , Pallavi Kadam , Ranjit Menon Date: Wed, 10 Jun 2020 16:45:00 +0200 Message-Id: <20200610144506.30505-2-david.marchand@redhat.com> In-Reply-To: <20200610144506.30505-1-david.marchand@redhat.com> References: <20200610144506.30505-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [dpdk-dev] [PATCH 1/7] eal: relocate per thread symbols to common 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" We have per lcore thread symbols scattered in OS implementations but common code relies on them. Move all of them in common. RTE_PER_LCORE(_socket_id) and RTE_PER_LCORE(_cpuset) have public accessors and are not exported through the library map, they can be made static. Signed-off-by: David Marchand --- lib/librte_eal/common/eal_common_thread.c | 5 ++++- lib/librte_eal/freebsd/eal_thread.c | 4 ---- lib/librte_eal/include/rte_lcore.h | 1 - lib/librte_eal/linux/eal_thread.c | 4 ---- lib/librte_eal/windows/eal_thread.c | 4 ---- 5 files changed, 4 insertions(+), 14 deletions(-) diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c index f9f588c173..25200e5a99 100644 --- a/lib/librte_eal/common/eal_common_thread.c +++ b/lib/librte_eal/common/eal_common_thread.c @@ -23,7 +23,10 @@ #include "eal_private.h" #include "eal_thread.h" -RTE_DECLARE_PER_LCORE(unsigned , _socket_id); +RTE_DEFINE_PER_LCORE(unsigned int, _lcore_id) = LCORE_ID_ANY; +static RTE_DEFINE_PER_LCORE(unsigned int, _socket_id) = + (unsigned int)SOCKET_ID_ANY; +static RTE_DEFINE_PER_LCORE(rte_cpuset_t, _cpuset); unsigned rte_socket_id(void) { diff --git a/lib/librte_eal/freebsd/eal_thread.c b/lib/librte_eal/freebsd/eal_thread.c index b52019782a..40676d9ef5 100644 --- a/lib/librte_eal/freebsd/eal_thread.c +++ b/lib/librte_eal/freebsd/eal_thread.c @@ -25,10 +25,6 @@ #include "eal_private.h" #include "eal_thread.h" -RTE_DEFINE_PER_LCORE(unsigned, _lcore_id) = LCORE_ID_ANY; -RTE_DEFINE_PER_LCORE(unsigned, _socket_id) = (unsigned)SOCKET_ID_ANY; -RTE_DEFINE_PER_LCORE(rte_cpuset_t, _cpuset); - /* * Send a message to a slave lcore identified by slave_id to call a * function f with argument arg. Once the execution is done, the diff --git a/lib/librte_eal/include/rte_lcore.h b/lib/librte_eal/include/rte_lcore.h index 339046bc86..5c1d1926e9 100644 --- a/lib/librte_eal/include/rte_lcore.h +++ b/lib/librte_eal/include/rte_lcore.h @@ -23,7 +23,6 @@ extern "C" { #define LCORE_ID_ANY UINT32_MAX /**< Any lcore. */ RTE_DECLARE_PER_LCORE(unsigned, _lcore_id); /**< Per thread "lcore id". */ -RTE_DECLARE_PER_LCORE(rte_cpuset_t, _cpuset); /**< Per thread "cpuset". */ /** * Get a lcore's role. diff --git a/lib/librte_eal/linux/eal_thread.c b/lib/librte_eal/linux/eal_thread.c index cd9d6e0ebf..a52ebef3a4 100644 --- a/lib/librte_eal/linux/eal_thread.c +++ b/lib/librte_eal/linux/eal_thread.c @@ -25,10 +25,6 @@ #include "eal_private.h" #include "eal_thread.h" -RTE_DEFINE_PER_LCORE(unsigned, _lcore_id) = LCORE_ID_ANY; -RTE_DEFINE_PER_LCORE(unsigned, _socket_id) = (unsigned)SOCKET_ID_ANY; -RTE_DEFINE_PER_LCORE(rte_cpuset_t, _cpuset); - /* * Send a message to a slave lcore identified by slave_id to call a * function f with argument arg. Once the execution is done, the diff --git a/lib/librte_eal/windows/eal_thread.c b/lib/librte_eal/windows/eal_thread.c index e149199a6f..fc245ceb05 100644 --- a/lib/librte_eal/windows/eal_thread.c +++ b/lib/librte_eal/windows/eal_thread.c @@ -16,10 +16,6 @@ #include "eal_private.h" #include "eal_windows.h" -RTE_DEFINE_PER_LCORE(unsigned int, _lcore_id) = LCORE_ID_ANY; -RTE_DEFINE_PER_LCORE(unsigned int, _socket_id) = (unsigned int)SOCKET_ID_ANY; -RTE_DEFINE_PER_LCORE(rte_cpuset_t, _cpuset); - /* * Send a message to a slave lcore identified by slave_id to call a * function f with argument arg. Once the execution is done, the From patchwork Wed Jun 10 14:45:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 71197 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id CD562A051F; Wed, 10 Jun 2020 16:45:50 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8EFDC1BFBD; Wed, 10 Jun 2020 16:45:49 +0200 (CEST) Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) by dpdk.org (Postfix) with ESMTP id E93101BFBC for ; Wed, 10 Jun 2020 16:45:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1591800347; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9FaMFDHgKlWZmsyIPxZi5/GDnUQ+CgJcHvCQgy0ISZ0=; b=c6jUSYK3fSfvCNk7oIK1e1mxCekHLlU5nQNhawRv8aGuarcRolDIzYjnjeAjZwbnYDg+99 d5TQkhf2sa4UTtYzxVjptL2MTC6E5xBsPEZc0d4cFD9gNcPkE5MZpdLT8H3pVi6wnOsN03 wBA6G9TlAqyN9DG0LvQtASIKizLdWsk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-366-DNda1XD4NfKFYbnbsRuInw-1; Wed, 10 Jun 2020 10:45:43 -0400 X-MC-Unique: DNda1XD4NfKFYbnbsRuInw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B65BE107ACF4; Wed, 10 Jun 2020 14:45:41 +0000 (UTC) Received: from dmarchan.remote.csb (unknown [10.40.192.116]) by smtp.corp.redhat.com (Postfix) with ESMTP id DA29760BF3; Wed, 10 Jun 2020 14:45:39 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Ray Kinsella , Neil Horman , Cunming Liang , Konstantin Ananyev , Olivier Matz Date: Wed, 10 Jun 2020 16:45:01 +0200 Message-Id: <20200610144506.30505-3-david.marchand@redhat.com> In-Reply-To: <20200610144506.30505-1-david.marchand@redhat.com> References: <20200610144506.30505-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [dpdk-dev] [PATCH 2/7] eal: fix multiple definition of per lcore thread id 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" Because of the inline accessor + static declaration in rte_gettid(), we end up with multiple symbols for RTE_PER_LCORE(_thread_id). Each compilation unit will pay a cost when accessing this information for the first time. $ nm build/app/dpdk-testpmd | grep per_lcore__thread_id 0000000000000054 d per_lcore__thread_id.5037 0000000000000040 d per_lcore__thread_id.5103 0000000000000048 d per_lcore__thread_id.5259 000000000000004c d per_lcore__thread_id.5259 0000000000000044 d per_lcore__thread_id.5933 0000000000000058 d per_lcore__thread_id.6261 0000000000000050 d per_lcore__thread_id.7378 000000000000005c d per_lcore__thread_id.7496 000000000000000c d per_lcore__thread_id.8016 0000000000000010 d per_lcore__thread_id.8431 Make it global as part of the DPDK_21 stable ABI. Fixes: ef76436c6834 ("eal: get unique thread id") Signed-off-by: David Marchand Acked-by: Ray Kinsella --- lib/librte_eal/common/eal_common_thread.c | 1 + lib/librte_eal/include/rte_eal.h | 3 ++- lib/librte_eal/rte_eal_version.map | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c index 25200e5a99..f04d880880 100644 --- a/lib/librte_eal/common/eal_common_thread.c +++ b/lib/librte_eal/common/eal_common_thread.c @@ -24,6 +24,7 @@ #include "eal_thread.h" RTE_DEFINE_PER_LCORE(unsigned int, _lcore_id) = LCORE_ID_ANY; +RTE_DEFINE_PER_LCORE(int, _thread_id) = -1; static RTE_DEFINE_PER_LCORE(unsigned int, _socket_id) = (unsigned int)SOCKET_ID_ANY; static RTE_DEFINE_PER_LCORE(rte_cpuset_t, _cpuset); diff --git a/lib/librte_eal/include/rte_eal.h b/lib/librte_eal/include/rte_eal.h index 2f9ed298de..2edf8c6556 100644 --- a/lib/librte_eal/include/rte_eal.h +++ b/lib/librte_eal/include/rte_eal.h @@ -447,6 +447,8 @@ enum rte_intr_mode rte_eal_vfio_intr_mode(void); */ int rte_sys_gettid(void); +RTE_DECLARE_PER_LCORE(int, _thread_id); + /** * Get system unique thread id. * @@ -456,7 +458,6 @@ int rte_sys_gettid(void); */ static inline int rte_gettid(void) { - static RTE_DEFINE_PER_LCORE(int, _thread_id) = -1; if (RTE_PER_LCORE(_thread_id) == -1) RTE_PER_LCORE(_thread_id) = rte_sys_gettid(); return RTE_PER_LCORE(_thread_id); diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index d8038749a4..fdfc3f1a88 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -221,6 +221,13 @@ DPDK_20.0 { local: *; }; +DPDK_21 { + global: + + per_lcore__thread_id; + +} DPDK_20.0; + EXPERIMENTAL { global: From patchwork Wed Jun 10 14:45:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 71198 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E5CBAA051F; Wed, 10 Jun 2020 16:46:02 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3061D1BFC8; Wed, 10 Jun 2020 16:45:53 +0200 (CEST) Received: from us-smtp-delivery-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) by dpdk.org (Postfix) with ESMTP id CA5DD1BFE5 for ; Wed, 10 Jun 2020 16:45:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1591800351; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gPo0nht675RqRoNtIN6IzPAcuMLCoAEXVa2VDRTzftc=; b=D2n4PAQPgS8si7IJRbAziAA5kFRRMHE8+gaWvJEQB3sj9HSiFnTm93yU6cQVEaUJjm3KzU +fnCgDTqorH6JF9GORq00Wsx4iX0JhK+Xrtf/0WhkrIl+I3bLxKGiNmSLcRwndhAaC5qOn ZQ3m1+i9v7YbivMS5zIP0nD7U+NMsq8= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-433-rSPPAAWnPnyKxzL_EavFhA-1; Wed, 10 Jun 2020 10:45:48 -0400 X-MC-Unique: rSPPAAWnPnyKxzL_EavFhA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 98364108BD0A; Wed, 10 Jun 2020 14:45:46 +0000 (UTC) Received: from dmarchan.remote.csb (unknown [10.40.192.116]) by smtp.corp.redhat.com (Postfix) with ESMTP id F075360BF3; Wed, 10 Jun 2020 14:45:44 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Bruce Richardson , Harini Ramakrishnan , Omar Cardona , Pallavi Kadam , Ranjit Menon Date: Wed, 10 Jun 2020 16:45:02 +0200 Message-Id: <20200610144506.30505-4-david.marchand@redhat.com> In-Reply-To: <20200610144506.30505-1-david.marchand@redhat.com> References: <20200610144506.30505-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [dpdk-dev] [PATCH 3/7] eal: introduce thread init helper 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" Introduce a helper responsible for initialising the per thread context. We can then have a unified context for EAL and non-EAL threads and remove copy/paste'd OS-specific helpers. Per EAL thread CPU affinity setting is separated from the thread init. It is to accommodate with Windows EAL where CPU affinity is not set at the moment. Besides, having affinity set by the master lcore in FreeBSD and Linux will make it possible to detect errors rather than panic in the child thread. But the cleanup when such an event happens is left for later. Document Windows limitation wrt recursive locks not working because of lack of gettid(). Signed-off-by: David Marchand --- lib/librte_eal/common/eal_common_thread.c | 58 ++++++++++++++--------- lib/librte_eal/common/eal_thread.h | 8 ++-- lib/librte_eal/freebsd/eal.c | 14 +++++- lib/librte_eal/freebsd/eal_thread.c | 32 +------------ lib/librte_eal/linux/eal.c | 15 +++++- lib/librte_eal/linux/eal_thread.c | 32 +------------ lib/librte_eal/windows/eal.c | 3 +- lib/librte_eal/windows/eal_thread.c | 10 +--- 8 files changed, 72 insertions(+), 100 deletions(-) diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c index f04d880880..fd5c41a2af 100644 --- a/lib/librte_eal/common/eal_common_thread.c +++ b/lib/librte_eal/common/eal_common_thread.c @@ -73,20 +73,10 @@ eal_cpuset_socket_id(rte_cpuset_t *cpusetp) return socket_id; } -int -rte_thread_set_affinity(rte_cpuset_t *cpusetp) +static void +thread_update_affinity(rte_cpuset_t *cpusetp) { - int s; - unsigned lcore_id; - pthread_t tid; - - tid = pthread_self(); - - s = pthread_setaffinity_np(tid, sizeof(rte_cpuset_t), cpusetp); - if (s != 0) { - RTE_LOG(ERR, EAL, "pthread_setaffinity_np failed\n"); - return -1; - } + unsigned int lcore_id = rte_lcore_id(); /* store socket_id in TLS for quick access */ RTE_PER_LCORE(_socket_id) = @@ -96,14 +86,24 @@ rte_thread_set_affinity(rte_cpuset_t *cpusetp) memmove(&RTE_PER_LCORE(_cpuset), cpusetp, sizeof(rte_cpuset_t)); - lcore_id = rte_lcore_id(); if (lcore_id != (unsigned)LCORE_ID_ANY) { /* EAL thread will update lcore_config */ lcore_config[lcore_id].socket_id = RTE_PER_LCORE(_socket_id); memmove(&lcore_config[lcore_id].cpuset, cpusetp, sizeof(rte_cpuset_t)); } +} + +int +rte_thread_set_affinity(rte_cpuset_t *cpusetp) +{ + if (pthread_setaffinity_np(pthread_self(), sizeof(rte_cpuset_t), + cpusetp) != 0) { + RTE_LOG(ERR, EAL, "pthread_setaffinity_np failed\n"); + return -1; + } + thread_update_affinity(cpusetp); return 0; } @@ -149,6 +149,25 @@ eal_thread_dump_affinity(char *str, unsigned size) return ret; } +void +rte_thread_init(unsigned int lcore_id, rte_cpuset_t *cpuset) +{ + /* set the lcore ID in per-lcore memory area */ + RTE_PER_LCORE(_lcore_id) = lcore_id; + +#ifndef RTE_EXEC_ENV_WINDOWS + /* acquire system unique id */ + rte_gettid(); +#else + /* FIXME: gettid unimplemented => recursive locks can't work */ +#endif + + thread_update_affinity(cpuset); + +#ifndef RTE_EXEC_ENV_WINDOWS + __rte_trace_mem_per_thread_alloc(); +#endif +} struct rte_thread_ctrl_params { void *(*start_routine)(void *); @@ -156,16 +175,14 @@ struct rte_thread_ctrl_params { pthread_barrier_t configured; }; -static void *rte_thread_init(void *arg) +static void *ctrl_thread_init(void *arg) { int ret; - rte_cpuset_t *cpuset = &internal_config.ctrl_cpuset; struct rte_thread_ctrl_params *params = arg; void *(*start_routine)(void *) = params->start_routine; void *routine_arg = params->arg; - /* Store cpuset in TLS for quick access */ - memmove(&RTE_PER_LCORE(_cpuset), cpuset, sizeof(rte_cpuset_t)); + rte_thread_init(rte_lcore_id(), &internal_config.ctrl_cpuset); ret = pthread_barrier_wait(¶ms->configured); if (ret == PTHREAD_BARRIER_SERIAL_THREAD) { @@ -173,9 +190,6 @@ static void *rte_thread_init(void *arg) free(params); } -#ifndef RTE_EXEC_ENV_WINDOWS - __rte_trace_mem_per_thread_alloc(); -#endif return start_routine(routine_arg); } @@ -197,7 +211,7 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name, pthread_barrier_init(¶ms->configured, NULL, 2); - ret = pthread_create(thread, attr, rte_thread_init, (void *)params); + ret = pthread_create(thread, attr, ctrl_thread_init, (void *)params); if (ret != 0) { free(params); return -ret; diff --git a/lib/librte_eal/common/eal_thread.h b/lib/librte_eal/common/eal_thread.h index b40ed249ed..da5e7c93ba 100644 --- a/lib/librte_eal/common/eal_thread.h +++ b/lib/librte_eal/common/eal_thread.h @@ -16,12 +16,14 @@ __rte_noreturn void *eal_thread_loop(void *arg); /** - * Init per-lcore info for master thread + * Init per-lcore info in current thread. * * @param lcore_id - * identifier of master lcore + * identifier of lcore. + * @param cpuset + * CPU affinity for this thread. */ -void eal_thread_init_master(unsigned lcore_id); +void rte_thread_init(unsigned int lcore_id, rte_cpuset_t *cpuset); /** * Get the NUMA socket id from cpu id. diff --git a/lib/librte_eal/freebsd/eal.c b/lib/librte_eal/freebsd/eal.c index c41f265fac..b5ea11df16 100644 --- a/lib/librte_eal/freebsd/eal.c +++ b/lib/librte_eal/freebsd/eal.c @@ -877,7 +877,14 @@ rte_eal_init(int argc, char **argv) eal_check_mem_on_local_socket(); - eal_thread_init_master(rte_config.master_lcore); + if (pthread_setaffinity_np(pthread_self(), sizeof(rte_cpuset_t), + &lcore_config[rte_config.master_lcore].cpuset) != 0) { + rte_eal_init_alert("Cannot set affinity"); + rte_errno = EINVAL; + return -1; + } + rte_thread_init(rte_config.master_lcore, + &lcore_config[rte_config.master_lcore].cpuset); ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset)); @@ -908,6 +915,11 @@ rte_eal_init(int argc, char **argv) snprintf(thread_name, sizeof(thread_name), "lcore-slave-%d", i); rte_thread_setname(lcore_config[i].thread_id, thread_name); + + ret = pthread_setaffinity_np(lcore_config[i].thread_id, + sizeof(rte_cpuset_t), &lcore_config[i].cpuset); + if (ret != 0) + rte_panic("Cannot set affinity\n"); } /* diff --git a/lib/librte_eal/freebsd/eal_thread.c b/lib/librte_eal/freebsd/eal_thread.c index 40676d9ef5..c1fb8eb2d8 100644 --- a/lib/librte_eal/freebsd/eal_thread.c +++ b/lib/librte_eal/freebsd/eal_thread.c @@ -66,29 +66,6 @@ rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned slave_id) return rc; } -/* set affinity for current thread */ -static int -eal_thread_set_affinity(void) -{ - unsigned lcore_id = rte_lcore_id(); - - /* acquire system unique id */ - rte_gettid(); - - /* update EAL thread core affinity */ - return rte_thread_set_affinity(&lcore_config[lcore_id].cpuset); -} - -void eal_thread_init_master(unsigned lcore_id) -{ - /* set the lcore ID in per-lcore memory area */ - RTE_PER_LCORE(_lcore_id) = lcore_id; - - /* set CPU affinity */ - if (eal_thread_set_affinity() < 0) - rte_panic("cannot set affinity\n"); -} - /* main loop of threads */ __rte_noreturn void * eal_thread_loop(__rte_unused void *arg) @@ -113,19 +90,12 @@ eal_thread_loop(__rte_unused void *arg) m2s = lcore_config[lcore_id].pipe_master2slave[0]; s2m = lcore_config[lcore_id].pipe_slave2master[1]; - /* set the lcore ID in per-lcore memory area */ - RTE_PER_LCORE(_lcore_id) = lcore_id; - - /* set CPU affinity */ - if (eal_thread_set_affinity() < 0) - rte_panic("cannot set affinity\n"); + rte_thread_init(lcore_id, &lcore_config[lcore_id].cpuset); ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset)); - RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%p;cpuset=[%s%s])\n", lcore_id, thread_id, cpuset, ret == 0 ? "" : "..."); - __rte_trace_mem_per_thread_alloc(); rte_eal_trace_thread_lcore_ready(lcore_id, cpuset); /* read on our pipe to get commands */ diff --git a/lib/librte_eal/linux/eal.c b/lib/librte_eal/linux/eal.c index f162124a37..8638376b8a 100644 --- a/lib/librte_eal/linux/eal.c +++ b/lib/librte_eal/linux/eal.c @@ -1205,10 +1205,16 @@ rte_eal_init(int argc, char **argv) eal_check_mem_on_local_socket(); - eal_thread_init_master(rte_config.master_lcore); + if (pthread_setaffinity_np(pthread_self(), sizeof(rte_cpuset_t), + &lcore_config[rte_config.master_lcore].cpuset) != 0) { + rte_eal_init_alert("Cannot set affinity"); + rte_errno = EINVAL; + return -1; + } + rte_thread_init(rte_config.master_lcore, + &lcore_config[rte_config.master_lcore].cpuset); ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset)); - RTE_LOG(DEBUG, EAL, "Master lcore %u is ready (tid=%zx;cpuset=[%s%s])\n", rte_config.master_lcore, (uintptr_t)thread_id, cpuset, ret == 0 ? "" : "..."); @@ -1240,6 +1246,11 @@ rte_eal_init(int argc, char **argv) if (ret != 0) RTE_LOG(DEBUG, EAL, "Cannot set name for lcore thread\n"); + + ret = pthread_setaffinity_np(lcore_config[i].thread_id, + sizeof(rte_cpuset_t), &lcore_config[i].cpuset); + if (ret != 0) + rte_panic("Cannot set affinity\n"); } /* diff --git a/lib/librte_eal/linux/eal_thread.c b/lib/librte_eal/linux/eal_thread.c index a52ebef3a4..07aec0c44d 100644 --- a/lib/librte_eal/linux/eal_thread.c +++ b/lib/librte_eal/linux/eal_thread.c @@ -66,29 +66,6 @@ rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned slave_id) return rc; } -/* set affinity for current EAL thread */ -static int -eal_thread_set_affinity(void) -{ - unsigned lcore_id = rte_lcore_id(); - - /* acquire system unique id */ - rte_gettid(); - - /* update EAL thread core affinity */ - return rte_thread_set_affinity(&lcore_config[lcore_id].cpuset); -} - -void eal_thread_init_master(unsigned lcore_id) -{ - /* set the lcore ID in per-lcore memory area */ - RTE_PER_LCORE(_lcore_id) = lcore_id; - - /* set CPU affinity */ - if (eal_thread_set_affinity() < 0) - rte_panic("cannot set affinity\n"); -} - /* main loop of threads */ __rte_noreturn void * eal_thread_loop(__rte_unused void *arg) @@ -113,19 +90,12 @@ eal_thread_loop(__rte_unused void *arg) m2s = lcore_config[lcore_id].pipe_master2slave[0]; s2m = lcore_config[lcore_id].pipe_slave2master[1]; - /* set the lcore ID in per-lcore memory area */ - RTE_PER_LCORE(_lcore_id) = lcore_id; - - /* set CPU affinity */ - if (eal_thread_set_affinity() < 0) - rte_panic("cannot set affinity\n"); + rte_thread_init(lcore_id, &lcore_config[lcore_id].cpuset); ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset)); - RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%zx;cpuset=[%s%s])\n", lcore_id, (uintptr_t)thread_id, cpuset, ret == 0 ? "" : "..."); - __rte_trace_mem_per_thread_alloc(); rte_eal_trace_thread_lcore_ready(lcore_id, cpuset); /* read on our pipe to get commands */ diff --git a/lib/librte_eal/windows/eal.c b/lib/librte_eal/windows/eal.c index d084606a66..924a10d8d5 100644 --- a/lib/librte_eal/windows/eal.c +++ b/lib/librte_eal/windows/eal.c @@ -244,7 +244,8 @@ rte_eal_init(int argc, char **argv) if (fctret < 0) exit(1); - eal_thread_init_master(rte_config.master_lcore); + rte_thread_init(rte_config.master_lcore, + &lcore_config[rte_config.master_lcore].cpuset); RTE_LCORE_FOREACH_SLAVE(i) { diff --git a/lib/librte_eal/windows/eal_thread.c b/lib/librte_eal/windows/eal_thread.c index fc245ceb05..4f39db713e 100644 --- a/lib/librte_eal/windows/eal_thread.c +++ b/lib/librte_eal/windows/eal_thread.c @@ -53,13 +53,6 @@ rte_eal_remote_launch(lcore_function_t *f, void *arg, unsigned int slave_id) return 0; } -void -eal_thread_init_master(unsigned int lcore_id) -{ - /* set the lcore ID in per-lcore memory area */ - RTE_PER_LCORE(_lcore_id) = lcore_id; -} - static inline pthread_t eal_thread_self(void) { @@ -90,8 +83,7 @@ eal_thread_loop(void *arg __rte_unused) m2s = lcore_config[lcore_id].pipe_master2slave[0]; s2m = lcore_config[lcore_id].pipe_slave2master[1]; - /* set the lcore ID in per-lcore memory area */ - RTE_PER_LCORE(_lcore_id) = lcore_id; + rte_thread_init(lcore_id, &lcore_config[lcore_id].cpuset); RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%zx;cpuset=[%s])\n", lcore_id, (uintptr_t)thread_id, cpuset); From patchwork Wed Jun 10 14:45:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 71199 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7EE4DA051F; Wed, 10 Jun 2020 16:46:15 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 63FF51BFFC; Wed, 10 Jun 2020 16:45:55 +0200 (CEST) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) by dpdk.org (Postfix) with ESMTP id 4D57E1BFF8 for ; Wed, 10 Jun 2020 16:45:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1591800353; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FF2wvnHXoEpOGYgT4FheRoA8GEdNa0N/3GiXTUseySw=; b=Zu5EwqBiC760EzwQ+aVGsOmdIXdBC9EAsPXraDebNSDESuKMHU0WewIMw1rtbA2WHnOacP zooyQqaFy0P5FZGCxm752r2itc3j5663GkBlVk3pfChUmXrsTl8EEUhoE7noURiZQ2YZzQ CzE22LoGPCJS4fuWhPfVGFSofqazGjs= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-485-Jj8wl9TKOQqHNrrEVPlLtg-1; Wed, 10 Jun 2020 10:45:51 -0400 X-MC-Unique: Jj8wl9TKOQqHNrrEVPlLtg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 874D080ED8F; Wed, 10 Jun 2020 14:45:50 +0000 (UTC) Received: from dmarchan.remote.csb (unknown [10.40.192.116]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7D36960BF3; Wed, 10 Jun 2020 14:45:49 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Jerin Jacob , Sunil Kumar Kori Date: Wed, 10 Jun 2020 16:45:03 +0200 Message-Id: <20200610144506.30505-5-david.marchand@redhat.com> In-Reply-To: <20200610144506.30505-1-david.marchand@redhat.com> References: <20200610144506.30505-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [dpdk-dev] [PATCH 4/7] eal: introduce thread uninit helper 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" This is a preparation step for dynamically unregistering external threads. Since we explicitly allocate a per thread trace buffer in rte_thread_init, add an internal helper to free this buffer. Note: I preferred renaming the current internal function to free all threads trace buffers (new name trace_mem_free()) and reuse the previous name (trace_mem_per_thread_free()) when freeing this buffer for a given thread. Signed-off-by: David Marchand --- lib/librte_eal/common/eal_common_thread.c | 9 +++++ lib/librte_eal/common/eal_common_trace.c | 49 +++++++++++++++++++---- lib/librte_eal/common/eal_thread.h | 5 +++ lib/librte_eal/common/eal_trace.h | 1 + 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c index fd5c41a2af..8a973ca8ac 100644 --- a/lib/librte_eal/common/eal_common_thread.c +++ b/lib/librte_eal/common/eal_common_thread.c @@ -22,6 +22,7 @@ #include "eal_internal_cfg.h" #include "eal_private.h" #include "eal_thread.h" +#include "eal_trace.h" RTE_DEFINE_PER_LCORE(unsigned int, _lcore_id) = LCORE_ID_ANY; RTE_DEFINE_PER_LCORE(int, _thread_id) = -1; @@ -169,6 +170,14 @@ rte_thread_init(unsigned int lcore_id, rte_cpuset_t *cpuset) #endif } +void +rte_thread_uninit(void) +{ +#ifndef RTE_EXEC_ENV_WINDOWS + trace_mem_per_thread_free(); +#endif +} + struct rte_thread_ctrl_params { void *(*start_routine)(void *); void *arg; diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c index 875553d7e5..cd2d217b02 100644 --- a/lib/librte_eal/common/eal_common_trace.c +++ b/lib/librte_eal/common/eal_common_trace.c @@ -101,7 +101,7 @@ eal_trace_fini(void) { if (!rte_trace_is_enabled()) return; - trace_mem_per_thread_free(); + trace_mem_free(); trace_metadata_destroy(); eal_trace_args_free(); } @@ -370,24 +370,59 @@ __rte_trace_mem_per_thread_alloc(void) rte_spinlock_unlock(&trace->lock); } +static void +trace_mem_per_thread_free_unlocked(struct thread_mem_meta *meta) +{ + if (meta->area == TRACE_AREA_HUGEPAGE) + eal_free_no_trace(meta->mem); + else if (meta->area == TRACE_AREA_HEAP) + free(meta->mem); +} + void trace_mem_per_thread_free(void) +{ + struct trace *trace = trace_obj_get(); + struct __rte_trace_header *header; + uint32_t count; + + if (RTE_PER_LCORE(trace_mem) == NULL) + return; + + header = RTE_PER_LCORE(trace_mem); + rte_spinlock_lock(&trace->lock); + for (count = 0; count < trace->nb_trace_mem_list; count++) { + if (trace->lcore_meta[count].mem == header) + break; + } + if (count != trace->nb_trace_mem_list) { + struct thread_mem_meta *meta = &trace->lcore_meta[count]; + + trace_mem_per_thread_free_unlocked(meta); + if (count != trace->nb_trace_mem_list - 1) { + memmove(meta, meta + 1, + sizeof(*meta) * + (trace->nb_trace_mem_list - count - 1)); + } + trace->nb_trace_mem_list--; + } + rte_spinlock_unlock(&trace->lock); +} + +void +trace_mem_free(void) { struct trace *trace = trace_obj_get(); uint32_t count; - void *mem; if (!rte_trace_is_enabled()) return; rte_spinlock_lock(&trace->lock); for (count = 0; count < trace->nb_trace_mem_list; count++) { - mem = trace->lcore_meta[count].mem; - if (trace->lcore_meta[count].area == TRACE_AREA_HUGEPAGE) - eal_free_no_trace(mem); - else if (trace->lcore_meta[count].area == TRACE_AREA_HEAP) - free(mem); + trace_mem_per_thread_free_unlocked(&trace->lcore_meta[count]); } + trace->nb_trace_mem_list = 0; rte_spinlock_unlock(&trace->lock); } diff --git a/lib/librte_eal/common/eal_thread.h b/lib/librte_eal/common/eal_thread.h index da5e7c93ba..4ecd8fd53a 100644 --- a/lib/librte_eal/common/eal_thread.h +++ b/lib/librte_eal/common/eal_thread.h @@ -25,6 +25,11 @@ __rte_noreturn void *eal_thread_loop(void *arg); */ void rte_thread_init(unsigned int lcore_id, rte_cpuset_t *cpuset); +/** + * Uninitialize per-lcore info for current thread. + */ +void rte_thread_uninit(void); + /** * Get the NUMA socket id from cpu id. * This function is private to EAL. diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h index 8f60616156..92c5951c3a 100644 --- a/lib/librte_eal/common/eal_trace.h +++ b/lib/librte_eal/common/eal_trace.h @@ -106,6 +106,7 @@ int trace_metadata_create(void); void trace_metadata_destroy(void); int trace_mkdir(void); int trace_epoch_time_save(void); +void trace_mem_free(void); void trace_mem_per_thread_free(void); /* EAL interface */ From patchwork Wed Jun 10 14:45:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 71200 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id CC886A051F; Wed, 10 Jun 2020 16:46:25 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A12471C00F; Wed, 10 Jun 2020 16:46:02 +0200 (CEST) Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [207.211.31.81]) by dpdk.org (Postfix) with ESMTP id CC57D1BFBC for ; Wed, 10 Jun 2020 16:46:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1591800360; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xAMULclat2XP3oLftyr3PDAhDwd+D32BhzURYFojcQo=; b=ACDSx0r7Nc9EGTPy6HJeRPslD6H7joeYMlUjyFS6HbnrYGJWrCZexVI3OcYnshoZkxEjcE zYljCLqkRKKUxbr1zgdW9U9atyR5XNzYBO5JSjg5dEU+UcMz4cjg8oUmNUa5YmYAWjdnLI g4Eroi/Sl0YK3gnxx59HsFZoyFb0gaE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-377-wF6X3tthN3mu2QjFGnQ8sQ-1; Wed, 10 Jun 2020 10:45:56 -0400 X-MC-Unique: wF6X3tthN3mu2QjFGnQ8sQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D454F8014D9; Wed, 10 Jun 2020 14:45:54 +0000 (UTC) Received: from dmarchan.remote.csb (unknown [10.40.192.116]) by smtp.corp.redhat.com (Postfix) with ESMTP id 696FC60BF3; Wed, 10 Jun 2020 14:45:53 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: John McNamara , Marko Kovacevic , Ray Kinsella , Neil Horman Date: Wed, 10 Jun 2020 16:45:04 +0200 Message-Id: <20200610144506.30505-6-david.marchand@redhat.com> In-Reply-To: <20200610144506.30505-1-david.marchand@redhat.com> References: <20200610144506.30505-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [dpdk-dev] [PATCH 5/7] eal: register non-EAL threads as lcore 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" DPDK allows calling some part of its API from a non-EAL thread but this has some limitations. OVS (and other applications) has its own thread management but still want to avoid such limitations by hacking RTE_PER_LCORE(_lcore_id) and faking EAL threads potentially unknown of some DPDK component. Introduce a new API to register non-EAL thread and associate them to a free lcore with a new EXTERNAL role. This role denotes lcores that do not run DPDK mainloop and as such prevents use of rte_eal_wait_lcore() and consorts. Signed-off-by: David Marchand Acked-by: Ray Kinsella --- doc/guides/howto/debug_troubleshoot.rst | 5 ++- lib/librte_eal/common/eal_common_lcore.c | 44 +++++++++++++++++-- lib/librte_eal/common/eal_common_thread.c | 45 ++++++++++++++++++++ lib/librte_eal/common/eal_private.h | 17 ++++++++ lib/librte_eal/include/rte_eal.h | 9 ---- lib/librte_eal/include/rte_lcore.h | 52 +++++++++++++++++------ lib/librte_eal/rte_eal_version.map | 4 ++ 7 files changed, 147 insertions(+), 29 deletions(-) diff --git a/doc/guides/howto/debug_troubleshoot.rst b/doc/guides/howto/debug_troubleshoot.rst index cef016b2fe..056f556a73 100644 --- a/doc/guides/howto/debug_troubleshoot.rst +++ b/doc/guides/howto/debug_troubleshoot.rst @@ -307,8 +307,9 @@ Custom worker function :numref:`dtg_distributor_worker`. #. Configuration issue isolation - * Identify core role using ``rte_eal_lcore_role`` to identify RTE, OFF and - SERVICE. Check performance functions are mapped to run on the cores. + * Identify core role using ``rte_eal_lcore_role`` to identify RTE, OFF, + SERVICE and EXTERNAL. Check performance functions are mapped to run on the + cores. * For high-performance execution logic ensure running it on correct NUMA and non-master core. diff --git a/lib/librte_eal/common/eal_common_lcore.c b/lib/librte_eal/common/eal_common_lcore.c index 5404922a87..35d6c1295e 100644 --- a/lib/librte_eal/common/eal_common_lcore.c +++ b/lib/librte_eal/common/eal_common_lcore.c @@ -6,13 +6,15 @@ #include #include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include "eal_internal_cfg.h" #include "eal_private.h" #include "eal_thread.h" @@ -209,3 +211,37 @@ rte_socket_id_by_idx(unsigned int idx) } return config->numa_nodes[idx]; } + +rte_spinlock_t external_lcore_lock = RTE_SPINLOCK_INITIALIZER; + +unsigned int +eal_lcore_external_reserve(void) +{ + struct rte_config *cfg = rte_eal_get_configuration(); + unsigned int lcore_id; + + rte_spinlock_lock(&external_lcore_lock); + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + if (rte_eal_lcore_role(lcore_id) != ROLE_OFF) + continue; + cfg->lcore_role[lcore_id] = ROLE_EXTERNAL; + cfg->lcore_count++; + break; + } + rte_spinlock_unlock(&external_lcore_lock); + + return lcore_id; +} + +void +eal_lcore_external_release(unsigned int lcore_id) +{ + struct rte_config *cfg = rte_eal_get_configuration(); + + rte_spinlock_lock(&external_lcore_lock); + if (rte_eal_lcore_role(lcore_id) == ROLE_EXTERNAL) { + cfg->lcore_role[lcore_id] = ROLE_OFF; + cfg->lcore_count--; + } + rte_spinlock_unlock(&external_lcore_lock); +} diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c index 8a973ca8ac..d57a6ec797 100644 --- a/lib/librte_eal/common/eal_common_thread.c +++ b/lib/librte_eal/common/eal_common_thread.c @@ -29,6 +29,7 @@ RTE_DEFINE_PER_LCORE(int, _thread_id) = -1; static RTE_DEFINE_PER_LCORE(unsigned int, _socket_id) = (unsigned int)SOCKET_ID_ANY; static RTE_DEFINE_PER_LCORE(rte_cpuset_t, _cpuset); +static RTE_DEFINE_PER_LCORE(bool, thread_registered); unsigned rte_socket_id(void) { @@ -255,3 +256,47 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name, pthread_join(*thread, NULL); return -ret; } + +void +rte_thread_register(void) +{ + unsigned int lcore_id; + rte_cpuset_t cpuset; + + /* EAL init flushes all lcores, we can't register before. */ + assert(internal_config.init_complete == 1); + + if (RTE_PER_LCORE(thread_registered)) + return; + + if (pthread_getaffinity_np(pthread_self(), sizeof(cpuset), + &cpuset) != 0) + CPU_ZERO(&cpuset); + + lcore_id = eal_lcore_external_reserve(); + if (lcore_id >= RTE_MAX_LCORE) + lcore_id = LCORE_ID_ANY; + + rte_thread_init(lcore_id, &cpuset); + + RTE_LOG(DEBUG, EAL, "Registered thread as lcore %u.\n", lcore_id); + RTE_PER_LCORE(thread_registered) = true; +} + +void +rte_thread_unregister(void) +{ + unsigned int lcore_id; + + if (!RTE_PER_LCORE(thread_registered)) + return; + + lcore_id = RTE_PER_LCORE(_lcore_id); + if (lcore_id != LCORE_ID_ANY) + eal_lcore_external_release(lcore_id); + + rte_thread_uninit(); + + RTE_LOG(DEBUG, EAL, "Unregistered thread (was lcore %u).\n", lcore_id); + RTE_PER_LCORE(thread_registered) = false; +} diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index 869ce183ad..8dd850f68a 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -274,6 +274,23 @@ uint64_t get_tsc_freq(void); */ uint64_t get_tsc_freq_arch(void); +/** + * Ask for a free lcore to associate to a non-EAL thread. + * + * @return + * The id of a lcore with role ROLE_EXTERNAL or RTE_MAX_LCORE if none was + * available. + */ +unsigned int eal_lcore_external_reserve(void); + +/** + * Release an external lcore. + * + * @param lcore_id + * The lcore with role ROLE_EXTERNAL to release. + */ +void eal_lcore_external_release(unsigned int lcore_id); + /** * Prepare physical memory mapping * i.e. hugepages on Linux and diff --git a/lib/librte_eal/include/rte_eal.h b/lib/librte_eal/include/rte_eal.h index 2edf8c6556..0913d1947c 100644 --- a/lib/librte_eal/include/rte_eal.h +++ b/lib/librte_eal/include/rte_eal.h @@ -31,15 +31,6 @@ extern "C" { /* Maximum thread_name length. */ #define RTE_MAX_THREAD_NAME_LEN 16 -/** - * The lcore role (used in RTE or not). - */ -enum rte_lcore_role_t { - ROLE_RTE, - ROLE_OFF, - ROLE_SERVICE, -}; - /** * The type of process in a linux, multi-process setup */ diff --git a/lib/librte_eal/include/rte_lcore.h b/lib/librte_eal/include/rte_lcore.h index 5c1d1926e9..d59c4edc67 100644 --- a/lib/librte_eal/include/rte_lcore.h +++ b/lib/librte_eal/include/rte_lcore.h @@ -24,6 +24,16 @@ extern "C" { RTE_DECLARE_PER_LCORE(unsigned, _lcore_id); /**< Per thread "lcore id". */ +/** + * The lcore role (used in RTE or not). + */ +enum rte_lcore_role_t { + ROLE_RTE, + ROLE_OFF, + ROLE_SERVICE, + ROLE_EXTERNAL, +}; + /** * Get a lcore's role. * @@ -34,6 +44,20 @@ RTE_DECLARE_PER_LCORE(unsigned, _lcore_id); /**< Per thread "lcore id". */ */ enum rte_lcore_role_t rte_eal_lcore_role(unsigned int lcore_id); +/** + * Test if the core supplied has a specific role + * + * @param lcore_id + * The identifier of the lcore, which MUST be between 0 and + * RTE_MAX_LCORE-1. + * @param role + * The role to be checked against. + * @return + * Boolean value: positive if test is true; otherwise returns 0. + */ +int +rte_lcore_has_role(unsigned int lcore_id, enum rte_lcore_role_t role); + /** * Return the Application thread ID of the execution unit. * @@ -256,6 +280,20 @@ int rte_thread_setname(pthread_t id, const char *name); __rte_experimental int rte_thread_getname(pthread_t id, char *name, size_t len); +/** + * Register current non-EAL thread as a lcore. + */ +__rte_experimental +void +rte_thread_register(void); + +/** + * Unregister current thread and release lcore if one was associated. + */ +__rte_experimental +void +rte_thread_unregister(void); + /** * Create a control thread. * @@ -283,20 +321,6 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); -/** - * Test if the core supplied has a specific role - * - * @param lcore_id - * The identifier of the lcore, which MUST be between 0 and - * RTE_MAX_LCORE-1. - * @param role - * The role to be checked against. - * @return - * Boolean value: positive if test is true; otherwise returns 0. - */ -int -rte_lcore_has_role(unsigned int lcore_id, enum rte_lcore_role_t role); - #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index fdfc3f1a88..f5b68d2815 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -393,4 +393,8 @@ EXPERIMENTAL { rte_trace_point_lookup; rte_trace_regexp; rte_trace_save; + + # added in 20.08 + rte_thread_register; + rte_thread_unregister; }; From patchwork Wed Jun 10 14:45:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 71202 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4E699A051F; Wed, 10 Jun 2020 16:46:48 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 7AB131C05C; Wed, 10 Jun 2020 16:46:06 +0200 (CEST) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) by dpdk.org (Postfix) with ESMTP id E19341C027 for ; Wed, 10 Jun 2020 16:46:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1591800363; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=knJUZyC/ntiqw8GDcULqvzgooU7U/Izm6C6BNwpdyoM=; b=GIt9q6cHjhP715wfkvVuaK1OLC2So49FvEMpoia+Wx+ngVkbjDwgjD51Y7V+7q8R7vXDa2 87u5qd2ppcnKDqcsHzlMgjnQ65O0J7Bvrf5iN6lTfMiJwRlNDYF+A0Wc6nQzacDSgE5HnY nIN1udkAJvZwbotKjkQsOm2G6diz5Pw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-353-XfCMvN9WOcKrRypqSEPkWg-1; Wed, 10 Jun 2020 10:46:01 -0400 X-MC-Unique: XfCMvN9WOcKrRypqSEPkWg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 08B98107ACF4; Wed, 10 Jun 2020 14:45:58 +0000 (UTC) Received: from dmarchan.remote.csb (unknown [10.40.192.116]) by smtp.corp.redhat.com (Postfix) with ESMTP id C3A5560BF3; Wed, 10 Jun 2020 14:45:56 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Bruce Richardson , Ray Kinsella , Neil Horman Date: Wed, 10 Jun 2020 16:45:05 +0200 Message-Id: <20200610144506.30505-7-david.marchand@redhat.com> In-Reply-To: <20200610144506.30505-1-david.marchand@redhat.com> References: <20200610144506.30505-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [dpdk-dev] [PATCH 6/7] eal: dump lcores 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" Add a little helper to dump all lcores. Signed-off-by: David Marchand --- lib/librte_eal/common/eal_common_lcore.c | 32 +++++++++++++++++++++++ lib/librte_eal/common/eal_common_thread.c | 16 ++++++++---- lib/librte_eal/common/eal_thread.h | 13 +++++++-- lib/librte_eal/freebsd/eal.c | 2 +- lib/librte_eal/freebsd/eal_thread.c | 2 +- lib/librte_eal/include/rte_lcore.h | 10 +++++++ lib/librte_eal/linux/eal.c | 2 +- lib/librte_eal/linux/eal_thread.c | 2 +- lib/librte_eal/rte_eal_version.map | 1 + 9 files changed, 69 insertions(+), 11 deletions(-) diff --git a/lib/librte_eal/common/eal_common_lcore.c b/lib/librte_eal/common/eal_common_lcore.c index 35d6c1295e..6aca1b2fee 100644 --- a/lib/librte_eal/common/eal_common_lcore.c +++ b/lib/librte_eal/common/eal_common_lcore.c @@ -245,3 +245,35 @@ eal_lcore_external_release(unsigned int lcore_id) } rte_spinlock_unlock(&external_lcore_lock); } + +void +rte_lcore_dump(FILE *f) +{ + char cpuset[RTE_CPU_AFFINITY_STR_LEN]; + unsigned int lcore_id; + const char *role; + int ret; + + rte_spinlock_lock(&external_lcore_lock); + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + switch (rte_eal_lcore_role(lcore_id)) { + case ROLE_RTE: + role = "RTE"; + break; + case ROLE_SERVICE: + role = "SERVICE"; + break; + case ROLE_EXTERNAL: + role = "EXTERNAL"; + break; + default: + continue; + } + + ret = eal_thread_dump_affinity(&lcore_config[lcore_id].cpuset, + cpuset, sizeof(cpuset)); + fprintf(f, "lcore %u, role %s, cpuset %s%s\n", lcore_id, role, + cpuset, ret == 0 ? "" : "..."); + } + rte_spinlock_unlock(&external_lcore_lock); +} diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c index d57a6ec797..a81b192ff3 100644 --- a/lib/librte_eal/common/eal_common_thread.c +++ b/lib/librte_eal/common/eal_common_thread.c @@ -118,17 +118,14 @@ rte_thread_get_affinity(rte_cpuset_t *cpusetp) } int -eal_thread_dump_affinity(char *str, unsigned size) +eal_thread_dump_affinity(rte_cpuset_t *cpuset, char *str, unsigned int size) { - rte_cpuset_t cpuset; unsigned cpu; int ret; unsigned int out = 0; - rte_thread_get_affinity(&cpuset); - for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { - if (!CPU_ISSET(cpu, &cpuset)) + if (!CPU_ISSET(cpu, cpuset)) continue; ret = snprintf(str + out, @@ -151,6 +148,15 @@ eal_thread_dump_affinity(char *str, unsigned size) return ret; } +int +eal_thread_dump_current_affinity(char *str, unsigned int size) +{ + rte_cpuset_t cpuset; + + rte_thread_get_affinity(&cpuset); + return eal_thread_dump_affinity(&cpuset, str, size); +} + void rte_thread_init(unsigned int lcore_id, rte_cpuset_t *cpuset) { diff --git a/lib/librte_eal/common/eal_thread.h b/lib/librte_eal/common/eal_thread.h index 4ecd8fd53a..13ec252e01 100644 --- a/lib/librte_eal/common/eal_thread.h +++ b/lib/librte_eal/common/eal_thread.h @@ -47,13 +47,15 @@ unsigned eal_cpu_socket_id(unsigned cpu_id); #define RTE_CPU_AFFINITY_STR_LEN 256 /** - * Dump the current pthread cpuset. + * Dump the cpuset as a human readable string. * This function is private to EAL. * * Note: * If the dump size is greater than the size of given buffer, * the string will be truncated and with '\0' at the end. * + * @param cpuset + * The CPU affinity object to dump. * @param str * The string buffer the cpuset will dump to. * @param size @@ -62,6 +64,13 @@ unsigned eal_cpu_socket_id(unsigned cpu_id); * 0 for success, -1 if truncation happens. */ int -eal_thread_dump_affinity(char *str, unsigned size); +eal_thread_dump_affinity(rte_cpuset_t *cpuset, char *str, unsigned int size); + +/** + * Dump the current thread cpuset. + * This is a wrapper on eal_thread_dump_affinity(). + */ +int +eal_thread_dump_current_affinity(char *str, unsigned int size); #endif /* EAL_THREAD_H */ diff --git a/lib/librte_eal/freebsd/eal.c b/lib/librte_eal/freebsd/eal.c index b5ea11df16..69a6f7d8c4 100644 --- a/lib/librte_eal/freebsd/eal.c +++ b/lib/librte_eal/freebsd/eal.c @@ -886,7 +886,7 @@ rte_eal_init(int argc, char **argv) rte_thread_init(rte_config.master_lcore, &lcore_config[rte_config.master_lcore].cpuset); - ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset)); + ret = eal_thread_dump_current_affinity(cpuset, sizeof(cpuset)); RTE_LOG(DEBUG, EAL, "Master lcore %u is ready (tid=%p;cpuset=[%s%s])\n", rte_config.master_lcore, thread_id, cpuset, diff --git a/lib/librte_eal/freebsd/eal_thread.c b/lib/librte_eal/freebsd/eal_thread.c index c1fb8eb2d8..b1a3619f51 100644 --- a/lib/librte_eal/freebsd/eal_thread.c +++ b/lib/librte_eal/freebsd/eal_thread.c @@ -92,7 +92,7 @@ eal_thread_loop(__rte_unused void *arg) rte_thread_init(lcore_id, &lcore_config[lcore_id].cpuset); - ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset)); + ret = eal_thread_dump_current_affinity(cpuset, sizeof(cpuset)); RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%p;cpuset=[%s%s])\n", lcore_id, thread_id, cpuset, ret == 0 ? "" : "..."); diff --git a/lib/librte_eal/include/rte_lcore.h b/lib/librte_eal/include/rte_lcore.h index d59c4edc67..9cf34efef4 100644 --- a/lib/librte_eal/include/rte_lcore.h +++ b/lib/librte_eal/include/rte_lcore.h @@ -228,6 +228,16 @@ unsigned int rte_get_next_lcore(unsigned int i, int skip_master, int wrap); i X-Patchwork-Id: 71201 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id DD0E4A051F; Wed, 10 Jun 2020 16:46:37 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 536071C027; Wed, 10 Jun 2020 16:46:05 +0200 (CEST) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) by dpdk.org (Postfix) with ESMTP id C58B51C01E for ; Wed, 10 Jun 2020 16:46:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1591800363; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uQwpma5QaUr9+2bvXyERhAJJ90Q0bzi5jKaYEUyTHwM=; b=EkOlZLjmMg4q1OvcxdMKFlLy/0nPbyO7cCW3Tm49PlGPSQ2vr7bEtIZLVshNPoT4MmBPQk Dl5S+bqCFhHeTclrLolKvBckAVRyTrMxjL5YZKFV4i0pqd+HRN8ohhZ+wn8fPiJQbOvDYc V8Oss+6rpjxmmFIY7JD9iLMfuY/yBGU= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-470-Q_TJf47ZN4uOoWaOdEY1NQ-1; Wed, 10 Jun 2020 10:46:01 -0400 X-MC-Unique: Q_TJf47ZN4uOoWaOdEY1NQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 862D58015CE; Wed, 10 Jun 2020 14:46:00 +0000 (UTC) Received: from dmarchan.remote.csb (unknown [10.40.192.116]) by smtp.corp.redhat.com (Postfix) with ESMTP id 772F560BF3; Wed, 10 Jun 2020 14:45:59 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Ray Kinsella , Neil Horman Date: Wed, 10 Jun 2020 16:45:06 +0200 Message-Id: <20200610144506.30505-8-david.marchand@redhat.com> In-Reply-To: <20200610144506.30505-1-david.marchand@redhat.com> References: <20200610144506.30505-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [dpdk-dev] [PATCH 7/7] eal: add lcore hotplug notifications 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" Now that lcores can be dynamically allocated/freed, we will have to notify DPDK components and applications of such events for cases where per lcore context must be allocated/initialised. Signed-off-by: David Marchand --- lib/librte_eal/common/eal_common_lcore.c | 91 +++++++++++++++++++++++ lib/librte_eal/common/eal_common_thread.c | 11 ++- lib/librte_eal/common/eal_private.h | 26 +++++++ lib/librte_eal/include/rte_lcore.h | 49 ++++++++++++ lib/librte_eal/rte_eal_version.map | 2 + 5 files changed, 178 insertions(+), 1 deletion(-) diff --git a/lib/librte_eal/common/eal_common_lcore.c b/lib/librte_eal/common/eal_common_lcore.c index 6aca1b2fee..3a997d8115 100644 --- a/lib/librte_eal/common/eal_common_lcore.c +++ b/lib/librte_eal/common/eal_common_lcore.c @@ -212,6 +212,47 @@ rte_socket_id_by_idx(unsigned int idx) return config->numa_nodes[idx]; } +struct lcore_notifier { + TAILQ_ENTRY(lcore_notifier) next; + rte_lcore_notifier_cb cb; + void *arg; +}; +static TAILQ_HEAD(lcore_notifiers_head, lcore_notifier) lcore_notifiers = + TAILQ_HEAD_INITIALIZER(lcore_notifiers); +static rte_spinlock_t lcore_notifiers_lock = RTE_SPINLOCK_INITIALIZER; + +void * +rte_lcore_notifier_register(rte_lcore_notifier_cb cb, void *arg) +{ + struct lcore_notifier *notifier; + + if (cb == NULL) + return NULL; + + notifier = calloc(1, sizeof(*notifier)); + if (notifier == NULL) + return NULL; + + notifier->cb = cb; + notifier->arg = arg; + rte_spinlock_lock(&lcore_notifiers_lock); + TAILQ_INSERT_TAIL(&lcore_notifiers, notifier, next); + rte_spinlock_unlock(&lcore_notifiers_lock); + + return notifier; +} + +void +rte_lcore_notifier_unregister(void *handle) +{ + struct lcore_notifier *notifier = handle; + + rte_spinlock_lock(&lcore_notifiers_lock); + TAILQ_REMOVE(&lcore_notifiers, notifier, next); + rte_spinlock_unlock(&lcore_notifiers_lock); + free(notifier); +} + rte_spinlock_t external_lcore_lock = RTE_SPINLOCK_INITIALIZER; unsigned int @@ -277,3 +318,53 @@ rte_lcore_dump(FILE *f) } rte_spinlock_unlock(&external_lcore_lock); } + +int +eal_lcore_external_notify_allocated(unsigned int lcore_id) +{ + struct lcore_notifier *notifier; + int ret = 0; + + RTE_LOG(DEBUG, EAL, "New lcore %u.\n", lcore_id); + rte_spinlock_lock(&lcore_notifiers_lock); + TAILQ_FOREACH(notifier, &lcore_notifiers, next) { + if (notifier->cb(lcore_id, RTE_LCORE_EVENT_NEW_EXTERNAL, + notifier->arg) == 0) + continue; + + /* Some notifier refused the new lcore, inform all notifiers + * that acked it. + */ + RTE_LOG(DEBUG, EAL, "A lcore notifier refused new lcore %u.\n", + lcore_id); + + notifier = TAILQ_PREV(notifier, lcore_notifiers_head, next); + while (notifier != NULL) { + notifier->cb(lcore_id, + RTE_LCORE_EVENT_RELEASE_EXTERNAL, + notifier->arg); + notifier = TAILQ_PREV(notifier, lcore_notifiers_head, + next); + } + ret = -1; + break; + } + rte_spinlock_unlock(&lcore_notifiers_lock); + + return ret; +} + +void +eal_lcore_external_notify_removed(unsigned int lcore_id) +{ + struct lcore_notifier *notifier; + + RTE_LOG(DEBUG, EAL, "Released lcore %u.\n", lcore_id); + rte_spinlock_lock(&lcore_notifiers_lock); + TAILQ_FOREACH_REVERSE(notifier, &lcore_notifiers, lcore_notifiers_head, + next) { + notifier->cb(lcore_id, RTE_LCORE_EVENT_RELEASE_EXTERNAL, + notifier->arg); + } + rte_spinlock_unlock(&lcore_notifiers_lock); +} diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c index a81b192ff3..f66d1ccaef 100644 --- a/lib/librte_eal/common/eal_common_thread.c +++ b/lib/librte_eal/common/eal_common_thread.c @@ -285,6 +285,12 @@ rte_thread_register(void) rte_thread_init(lcore_id, &cpuset); + if (lcore_id != LCORE_ID_ANY && + eal_lcore_external_notify_allocated(lcore_id) < 0) { + eal_lcore_external_release(lcore_id); + RTE_PER_LCORE(_lcore_id) = lcore_id = LCORE_ID_ANY; + } + RTE_LOG(DEBUG, EAL, "Registered thread as lcore %u.\n", lcore_id); RTE_PER_LCORE(thread_registered) = true; } @@ -298,8 +304,11 @@ rte_thread_unregister(void) return; lcore_id = RTE_PER_LCORE(_lcore_id); - if (lcore_id != LCORE_ID_ANY) + if (lcore_id != LCORE_ID_ANY) { + eal_lcore_external_notify_removed(lcore_id); eal_lcore_external_release(lcore_id); + RTE_PER_LCORE(_lcore_id) = LCORE_ID_ANY; + } rte_thread_uninit(); diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index 8dd850f68a..649697c368 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -283,6 +283,21 @@ uint64_t get_tsc_freq_arch(void); */ unsigned int eal_lcore_external_reserve(void); +/** + * Evaluate all lcore notifiers with a RTE_LCORE_EVENT_NEW_EXTERNAL event for + * the passed lcore. + * If an error is returned by one of them, then this change is rolled back: + * all previous lcore notifiers that had acked the RTE_LCORE_EVENT_NEW_EXTERNAL + * event receive a RTE_LCORE_EVENT_RELEASE_EXTERNAL event for the passed lcore. + * + * @param lcore_id + * The lcore to consider. + * @return + * - 0 if all notifiers agreed on the new lcore + * - -1 if one of them refused + */ +int eal_lcore_external_notify_allocated(unsigned int lcore_id); + /** * Release an external lcore. * @@ -291,6 +306,17 @@ unsigned int eal_lcore_external_reserve(void); */ void eal_lcore_external_release(unsigned int lcore_id); +/** + * Evaluate all lcore notifiers with a RTE_LCORE_EVENT_RELEASE_EXTERNAL event + * for the passed lcore. + * This function must be called with a lcore that successfully passed + * eal_lcore_external_notify_allocated(). + * + * @param lcore_id + * The lcore with role ROLE_EXTERNAL to release. + */ +void eal_lcore_external_notify_removed(unsigned int lcore_id); + /** * Prepare physical memory mapping * i.e. hugepages on Linux and diff --git a/lib/librte_eal/include/rte_lcore.h b/lib/librte_eal/include/rte_lcore.h index 9cf34efef4..e0fec33d5a 100644 --- a/lib/librte_eal/include/rte_lcore.h +++ b/lib/librte_eal/include/rte_lcore.h @@ -238,6 +238,55 @@ __rte_experimental void rte_lcore_dump(FILE *f); +enum rte_lcore_event_type { + RTE_LCORE_EVENT_NEW_EXTERNAL, + RTE_LCORE_EVENT_RELEASE_EXTERNAL, +}; + +/** + * Callback prototype for getting lcore events. + * + * @param lcore_id + * The lcore to consider for this event. + * @param event + * The type of event on the lcore. + * @param arg + * An opaque pointer passed at notifier registration. + * @return + * - -1 when refusing this event, + * - 0 otherwise. + */ +typedef int (*rte_lcore_notifier_cb)(unsigned int lcore_id, + enum rte_lcore_event_type event, void *arg); + +/** + * Register a lcore notifier. + * + * @param cb + * The callback invoked for each lcore event with the arg argument. + * See rte_lcore_notifier_cb description. + * @param arg + * An optional argument that gets passed to the callback when it gets + * invoked. + * @return + * On success, returns an opaque pointer for the created notifier. + * NULL on failure. + */ +__rte_experimental +void * +rte_lcore_notifier_register(rte_lcore_notifier_cb cb, void *arg); + +/** + * Unregister a lcore notifier. + * + * @param handle + * The handle pointer returned by a former successful call to + * rte_lcore_notifier_register. + */ +__rte_experimental +void +rte_lcore_notifier_unregister(void *handle); + /** * Set core affinity of the current thread. * Support both EAL and non-EAL thread and update TLS. diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 6754d52543..1e6f2aaacc 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -396,6 +396,8 @@ EXPERIMENTAL { # added in 20.08 rte_lcore_dump; + rte_lcore_notifier_register; + rte_lcore_notifier_unregister; rte_thread_register; rte_thread_unregister; };