From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF8F5C433DF for ; Mon, 22 Jun 2020 13:27:00 +0000 (UTC) Received: from dpdk.org (dpdk.org [92.243.14.124]) by mail.kernel.org (Postfix) with ESMTP id 5ABF620702 for ; Mon, 22 Jun 2020 13:27:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="esmootTR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5ABF620702 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=dev-bounces@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 792621D6D8; Mon, 22 Jun 2020 15:26:28 +0200 (CEST) Received: from us-smtp-delivery-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) by dpdk.org (Postfix) with ESMTP id 3C3AC1D6D8 for ; Mon, 22 Jun 2020 15:26:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1592832386; 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=ER6LVMDIisMPu2vKUZjsUZpoPOS9HWQyQfl5x4D9SjY=; b=esmootTRU5VAb591I1Sl6idd0OrxIbS9GQm3jWP8rX07/f7b2p+eoSmVOiHT92cOlWXwKn ljbiOka2Gd3wRVZLY7IJD5dqJqhtKLq3MOL8EzfsnwThvCpYMwG5GBXMfGQCNmjVTdgPIw /ktUJtjWOtBwxn9suH1NFYV/CCfNQxY= 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-242-5g8P1Oh4P9qo3KeHZywroQ-1; Mon, 22 Jun 2020 09:26:22 -0400 X-MC-Unique: 5g8P1Oh4P9qo3KeHZywroQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A338710059A0; Mon, 22 Jun 2020 13:26:20 +0000 (UTC) Received: from dmarchan.remote.csb (unknown [10.40.193.229]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1F7F41DC; Mon, 22 Jun 2020 13:26:15 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: jerinjacobk@gmail.com, bruce.richardson@intel.com, mdr@ashroe.eu, ktraynor@redhat.com, ian.stokes@intel.com, i.maximets@ovn.org, Thomas Monjalon , John McNamara , Marko Kovacevic , Anatoly Burakov , Olivier Matz , Andrew Rybchenko , Neil Horman Date: Mon, 22 Jun 2020 15:25:28 +0200 Message-Id: <20200622132531.21857-7-david.marchand@redhat.com> In-Reply-To: <20200622132531.21857-1-david.marchand@redhat.com> References: <20200610144506.30505-1-david.marchand@redhat.com> <20200622132531.21857-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH v3 6/9] eal: register non-EAL threads as 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" 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 NON_EAL 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 --- Changes since v1: - moved cleanup on lcore role code in patch 5, - added unit test, - updated documentation, - changed naming from "external thread" to "registered non-EAL thread" --- MAINTAINERS | 1 + app/test/Makefile | 1 + app/test/autotest_data.py | 6 + app/test/meson.build | 2 + app/test/test_lcores.c | 139 ++++++++++++++++++ doc/guides/howto/debug_troubleshoot.rst | 5 +- .../prog_guide/env_abstraction_layer.rst | 22 +-- doc/guides/prog_guide/mempool_lib.rst | 2 +- lib/librte_eal/common/eal_common_lcore.c | 44 +++++- lib/librte_eal/common/eal_common_thread.c | 33 +++++ lib/librte_eal/common/eal_private.h | 18 +++ lib/librte_eal/include/rte_lcore.h | 18 ++- lib/librte_eal/rte_eal_version.map | 2 + lib/librte_mempool/rte_mempool.h | 11 +- 14 files changed, 282 insertions(+), 22 deletions(-) create mode 100644 app/test/test_lcores.c diff --git a/MAINTAINERS b/MAINTAINERS index 816696caf2..fe9e74ffbc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -183,6 +183,7 @@ F: app/test/test_debug.c F: app/test/test_eal* F: app/test/test_errno.c F: app/test/test_interrupts.c +F: app/test/test_lcores.c F: app/test/test_logs.c F: app/test/test_memcpy* F: app/test/test_per_lcore.c diff --git a/app/test/Makefile b/app/test/Makefile index 7b96a03a64..4a8dea2425 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -97,6 +97,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_FLOW_CLASSIFY) += test_flow_classify.c endif SRCS-y += test_rwlock.c +SRCS-y += test_lcores.c SRCS-$(CONFIG_RTE_LIBRTE_STACK) += test_stack.c SRCS-$(CONFIG_RTE_LIBRTE_STACK) += test_stack_perf.c diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py index fc3fcc159e..600b130966 100644 --- a/app/test/autotest_data.py +++ b/app/test/autotest_data.py @@ -62,6 +62,12 @@ "Func": rwlock_autotest, "Report": None, }, + { + "Name": "Lcores autotest", + "Command": "lcores_autotest", + "Func": default_autotest, + "Report": None, + }, { "Name": "Logs autotest", "Command": "logs_autotest", diff --git a/app/test/meson.build b/app/test/meson.build index 5233ead46e..a57477b7cc 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -67,6 +67,7 @@ test_sources = files('commands.c', 'test_ipsec_perf.c', 'test_kni.c', 'test_kvargs.c', + 'test_lcores.c', 'test_logs.c', 'test_lpm.c', 'test_lpm6.c', @@ -206,6 +207,7 @@ fast_tests = [ ['hash_autotest', true], ['interrupt_autotest', true], ['ipfrag_autotest', false], + ['lcores_autotest', true], ['logs_autotest', true], ['lpm_autotest', true], ['lpm6_autotest', true], diff --git a/app/test/test_lcores.c b/app/test/test_lcores.c new file mode 100644 index 0000000000..864bcbade7 --- /dev/null +++ b/app/test/test_lcores.c @@ -0,0 +1,139 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2020 Red Hat, Inc. + */ + +#include +#include + +#include + +#include "test.h" + +struct thread_context { + enum { INIT, ERROR, DONE } state; + bool lcore_id_any; + pthread_t id; + unsigned int *registered_count; +}; +static void *thread_loop(void *arg) +{ + struct thread_context *t = arg; + unsigned int lcore_id; + + lcore_id = rte_lcore_id(); + if (lcore_id != LCORE_ID_ANY) { + printf("Incorrect lcore id for new thread %u\n", lcore_id); + t->state = ERROR; + } + rte_thread_register(); + lcore_id = rte_lcore_id(); + if ((t->lcore_id_any && lcore_id != LCORE_ID_ANY) || + (!t->lcore_id_any && lcore_id == LCORE_ID_ANY)) { + printf("Could not register new thread, got %u while %sexpecting %u\n", + lcore_id, t->lcore_id_any ? "" : "not ", LCORE_ID_ANY); + t->state = ERROR; + } + /* Report register happened to the control thread. */ + __atomic_add_fetch(t->registered_count, 1, __ATOMIC_RELEASE); + + /* Wait for release from the control thread. */ + while (__atomic_load_n(t->registered_count, __ATOMIC_ACQUIRE) != 0) + ; + rte_thread_unregister(); + lcore_id = rte_lcore_id(); + if (lcore_id != LCORE_ID_ANY) { + printf("Could not unregister new thread, %u still assigned\n", + lcore_id); + t->state = ERROR; + } + + if (t->state != ERROR) + t->state = DONE; + + return NULL; +} + +static int +test_non_eal_lcores(unsigned int eal_threads_count) +{ + struct thread_context thread_contexts[RTE_MAX_LCORE]; + unsigned int non_eal_threads_count; + unsigned int registered_count; + struct thread_context *t; + unsigned int i; + int ret; + + non_eal_threads_count = 0; + registered_count = 0; + + /* Try to create as many threads as possible. */ + for (i = 0; i < RTE_MAX_LCORE - eal_threads_count; i++) { + t = &thread_contexts[i]; + t->state = INIT; + t->registered_count = ®istered_count; + t->lcore_id_any = false; + if (pthread_create(&t->id, NULL, thread_loop, t) != 0) + break; + non_eal_threads_count++; + } + printf("non-EAL threads count: %u\n", non_eal_threads_count); + /* Wait all non-EAL threads to register. */ + while (__atomic_load_n(®istered_count, __ATOMIC_ACQUIRE) != + non_eal_threads_count) + ; + + /* We managed to create the max number of threads, let's try to create + * one more. This will allow one more check. + */ + if (eal_threads_count + non_eal_threads_count < RTE_MAX_LCORE) + goto skip_lcore_any; + t = &thread_contexts[non_eal_threads_count]; + t->state = INIT; + t->registered_count = ®istered_count; + t->lcore_id_any = true; + if (pthread_create(&t->id, NULL, thread_loop, t) == 0) { + non_eal_threads_count++; + printf("non-EAL threads count: %u\n", non_eal_threads_count); + while (__atomic_load_n(®istered_count, __ATOMIC_ACQUIRE) != + non_eal_threads_count) + ; + } + +skip_lcore_any: + /* Release all threads, and check their states. */ + __atomic_store_n(®istered_count, 0, __ATOMIC_RELEASE); + ret = 0; + for (i = 0; i < non_eal_threads_count; i++) { + t = &thread_contexts[i]; + pthread_join(t->id, NULL); + if (t->state != DONE) + ret = -1; + } + + return ret; +} + +static int +test_lcores(void) +{ + unsigned int eal_threads_count = 0; + unsigned int i; + + for (i = 0; i < RTE_MAX_LCORE; i++) { + if (!rte_lcore_has_role(i, ROLE_OFF)) + eal_threads_count++; + } + if (eal_threads_count == 0) { + printf("Something is broken, no EAL thread detected.\n"); + return TEST_FAILED; + } + printf("EAL threads count: %u, RTE_MAX_LCORE=%u\n", eal_threads_count, + RTE_MAX_LCORE); + + if (test_non_eal_lcores(eal_threads_count) < 0) + return TEST_FAILED; + + return TEST_SUCCESS; +} + +REGISTER_TEST_COMMAND(lcores_autotest, test_lcores); diff --git a/doc/guides/howto/debug_troubleshoot.rst b/doc/guides/howto/debug_troubleshoot.rst index cef016b2fe..5a46f5fba3 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 NON_EAL. 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/doc/guides/prog_guide/env_abstraction_layer.rst b/doc/guides/prog_guide/env_abstraction_layer.rst index 48a2fec066..f64ae953d1 100644 --- a/doc/guides/prog_guide/env_abstraction_layer.rst +++ b/doc/guides/prog_guide/env_abstraction_layer.rst @@ -564,9 +564,13 @@ It's also compatible with the pattern of corelist('-l') option. non-EAL pthread support ~~~~~~~~~~~~~~~~~~~~~~~ -It is possible to use the DPDK execution context with any user pthread (aka. Non-EAL pthreads). -In a non-EAL pthread, the *_lcore_id* is always LCORE_ID_ANY which identifies that it is not an EAL thread with a valid, unique, *_lcore_id*. -Some libraries will use an alternative unique ID (e.g. TID), some will not be impacted at all, and some will work but with limitations (e.g. timer and mempool libraries). +It is possible to use the DPDK execution context with any user pthread (aka. non-EAL pthreads). +There are two kinds of non-EAL pthreads: + +- a registered non-EAL pthread with a valid *_lcore_id* that was successfully assigned by calling ``rte_thread_register()``, +- a non registered non-EAL pthread with a LCORE_ID_ANY, + +For non registered non-EAL pthread (with a LCORE_ID_ANY *_lcore_id*), some libraries will use an alternative unique ID (e.g. TID), some will not be impacted at all, and some will work but with limitations (e.g. timer and mempool libraries). All these impacts are mentioned in :ref:`known_issue_label` section. @@ -613,9 +617,9 @@ Known Issues + rte_mempool The rte_mempool uses a per-lcore cache inside the mempool. - For non-EAL pthreads, ``rte_lcore_id()`` will not return a valid number. - So for now, when rte_mempool is used with non-EAL pthreads, the put/get operations will bypass the default mempool cache and there is a performance penalty because of this bypass. - Only user-owned external caches can be used in a non-EAL context in conjunction with ``rte_mempool_generic_put()`` and ``rte_mempool_generic_get()`` that accept an explicit cache parameter. + For unregistered non-EAL pthreads, ``rte_lcore_id()`` will not return a valid number. + So for now, when rte_mempool is used with unregistered non-EAL pthreads, the put/get operations will bypass the default mempool cache and there is a performance penalty because of this bypass. + Only user-owned external caches can be used in an unregistered non-EAL context in conjunction with ``rte_mempool_generic_put()`` and ``rte_mempool_generic_get()`` that accept an explicit cache parameter. + rte_ring @@ -660,15 +664,15 @@ Known Issues + rte_timer - Running ``rte_timer_manage()`` on a non-EAL pthread is not allowed. However, resetting/stopping the timer from a non-EAL pthread is allowed. + Running ``rte_timer_manage()`` on an unregistered non-EAL pthread is not allowed. However, resetting/stopping the timer from a non-EAL pthread is allowed. + rte_log - In non-EAL pthreads, there is no per thread loglevel and logtype, global loglevels are used. + In unregistered non-EAL pthreads, there is no per thread loglevel and logtype, global loglevels are used. + misc - The debug statistics of rte_ring, rte_mempool and rte_timer are not supported in a non-EAL pthread. + The debug statistics of rte_ring, rte_mempool and rte_timer are not supported in an unregistered non-EAL pthread. cgroup control ~~~~~~~~~~~~~~ diff --git a/doc/guides/prog_guide/mempool_lib.rst b/doc/guides/prog_guide/mempool_lib.rst index f8b430d656..e3e1f940be 100644 --- a/doc/guides/prog_guide/mempool_lib.rst +++ b/doc/guides/prog_guide/mempool_lib.rst @@ -103,7 +103,7 @@ The maximum size of the cache is static and is defined at compilation time (CONF Alternatively to the internal default per-lcore local cache, an application can create and manage external caches through the ``rte_mempool_cache_create()``, ``rte_mempool_cache_free()`` and ``rte_mempool_cache_flush()`` calls. These user-owned caches can be explicitly passed to ``rte_mempool_generic_put()`` and ``rte_mempool_generic_get()``. The ``rte_mempool_default_cache()`` call returns the default internal cache if any. -In contrast to the default caches, user-owned caches can be used by non-EAL threads too. +In contrast to the default caches, user-owned caches can be used by unregistered non-EAL threads too. Mempool Handlers ------------------------ diff --git a/lib/librte_eal/common/eal_common_lcore.c b/lib/librte_eal/common/eal_common_lcore.c index 86d32a3dd7..7db05428e7 100644 --- a/lib/librte_eal/common/eal_common_lcore.c +++ b/lib/librte_eal/common/eal_common_lcore.c @@ -6,12 +6,13 @@ #include #include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include #include "eal_private.h" #include "eal_thread.h" @@ -220,3 +221,38 @@ rte_socket_id_by_idx(unsigned int idx) } return config->numa_nodes[idx]; } + +static rte_spinlock_t lcore_lock = RTE_SPINLOCK_INITIALIZER; + +unsigned int +eal_lcore_non_eal_allocate(void) +{ + struct rte_config *cfg = rte_eal_get_configuration(); + unsigned int lcore_id; + + rte_spinlock_lock(&lcore_lock); + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + if (cfg->lcore_role[lcore_id] != ROLE_OFF) + continue; + cfg->lcore_role[lcore_id] = ROLE_NON_EAL; + cfg->lcore_count++; + break; + } + if (lcore_id == RTE_MAX_LCORE) + RTE_LOG(DEBUG, EAL, "No lcore available.\n"); + rte_spinlock_unlock(&lcore_lock); + return lcore_id; +} + +void +eal_lcore_non_eal_release(unsigned int lcore_id) +{ + struct rte_config *cfg = rte_eal_get_configuration(); + + rte_spinlock_lock(&lcore_lock); + if (cfg->lcore_role[lcore_id] == ROLE_NON_EAL) { + cfg->lcore_role[lcore_id] = ROLE_OFF; + cfg->lcore_count--; + } + rte_spinlock_unlock(&lcore_lock); +} diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c index a7ae0691bf..1cbddc4b5b 100644 --- a/lib/librte_eal/common/eal_common_thread.c +++ b/lib/librte_eal/common/eal_common_thread.c @@ -236,3 +236,36 @@ 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 (pthread_getaffinity_np(pthread_self(), sizeof(cpuset), + &cpuset) != 0) + CPU_ZERO(&cpuset); + lcore_id = eal_lcore_non_eal_allocate(); + if (lcore_id >= RTE_MAX_LCORE) + lcore_id = LCORE_ID_ANY; + rte_thread_init(lcore_id, &cpuset); + if (lcore_id != LCORE_ID_ANY) + RTE_LOG(DEBUG, EAL, "Registered non-EAL thread as lcore %u.\n", + lcore_id); +} + +void +rte_thread_unregister(void) +{ + unsigned int lcore_id = rte_lcore_id(); + + if (lcore_id != LCORE_ID_ANY) + eal_lcore_non_eal_release(lcore_id); + rte_thread_uninit(); + if (lcore_id != LCORE_ID_ANY) + RTE_LOG(DEBUG, EAL, "Unregistered non-EAL thread (was lcore %u).\n", + lcore_id); +} diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index 0592fcd694..73238ff157 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -396,6 +396,24 @@ uint64_t get_tsc_freq(void); */ uint64_t get_tsc_freq_arch(void); +/** + * Allocate a free lcore to associate to a non-EAL thread. + * + * @return + * - the id of a lcore with role ROLE_NON_EAL on success. + * - RTE_MAX_LCORE if none was available. + */ +unsigned int eal_lcore_non_eal_allocate(void); + +/** + * Release the lcore used by a non-EAL thread. + * Counterpart of eal_lcore_non_eal_allocate(). + * + * @param lcore_id + * The lcore with role ROLE_NON_EAL to release. + */ +void eal_lcore_non_eal_release(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 3968c40693..ea86220394 100644 --- a/lib/librte_eal/include/rte_lcore.h +++ b/lib/librte_eal/include/rte_lcore.h @@ -31,6 +31,7 @@ enum rte_lcore_role_t { ROLE_RTE, ROLE_OFF, ROLE_SERVICE, + ROLE_NON_EAL, }; /** @@ -67,7 +68,8 @@ rte_lcore_has_role(unsigned int lcore_id, enum rte_lcore_role_t role); * to run threads with lcore IDs 0, 1, 2 and 3 on physical core 10.. * * @return - * Logical core ID (in EAL thread) or LCORE_ID_ANY (in non-EAL thread) + * Logical core ID (in EAL thread or registered non-EAL thread) or + * LCORE_ID_ANY (in unregistered non-EAL thread) */ static inline unsigned rte_lcore_id(void) @@ -279,6 +281,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. * diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 5831eea4b0..39c41d445d 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_trace_mem_per_thread_free; + rte_thread_register; + rte_thread_unregister; }; INTERNAL { diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h index 652d19f9f1..9e0ee052b3 100644 --- a/lib/librte_mempool/rte_mempool.h +++ b/lib/librte_mempool/rte_mempool.h @@ -28,9 +28,9 @@ * rte_mempool_get() or rte_mempool_put() are designed to be called from an EAL * thread due to the internal per-lcore cache. Due to the lack of caching, * rte_mempool_get() or rte_mempool_put() performance will suffer when called - * by non-EAL threads. Instead, non-EAL threads should call - * rte_mempool_generic_get() or rte_mempool_generic_put() with a user cache - * created with rte_mempool_cache_create(). + * by unregistered non-EAL threads. Instead, unregistered non-EAL threads + * should call rte_mempool_generic_get() or rte_mempool_generic_put() with a + * user cache created with rte_mempool_cache_create(). */ #include @@ -1233,7 +1233,7 @@ void rte_mempool_dump(FILE *f, struct rte_mempool *mp); /** * Create a user-owned mempool cache. * - * This can be used by non-EAL threads to enable caching when they + * This can be used by unregistered non-EAL threads to enable caching when they * interact with a mempool. * * @param size @@ -1264,7 +1264,8 @@ rte_mempool_cache_free(struct rte_mempool_cache *cache); * @param lcore_id * The logical core id. * @return - * A pointer to the mempool cache or NULL if disabled or non-EAL thread. + * A pointer to the mempool cache or NULL if disabled or unregistered non-EAL + * thread. */ static __rte_always_inline struct rte_mempool_cache * rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id) -- 2.23.0