In order to make sure all threads created in DPDK drivers and libraries
have the same prefix in their name, some wrapper functions are added
for internal use when creating a control thread or setting a thread name:
- rte_thread_create_internal_control
- rte_thread_set_prefixed_name
The equivalent public functions are then forbidden for internal use:
- rte_thread_create_control
- rte_thread_set_name
Note: the libraries and drivers conversion is done in next patches,
while doing other thread-related changes.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
Acked-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
---
v2: simplify size doc + build time check of internal name size
v3: fix build of RTE_BUILD_BUG_ON
---
devtools/checkpatches.sh | 8 +++++
lib/eal/common/eal_common_thread.c | 33 +++++++++++++++++
lib/eal/include/rte_thread.h | 57 +++++++++++++++++++++++++++++-
lib/eal/version.map | 2 ++
4 files changed, 99 insertions(+), 1 deletion(-)
@@ -159,6 +159,14 @@ check_forbidden_additions() { # <patch>
-f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
"$1" || res=1
+ # forbid non-internal thread in drivers and libs
+ awk -v FOLDERS='lib drivers' \
+ -v EXPRESSIONS="rte_thread_(set_name|create_control)\\\(" \
+ -v RET_ON_FAIL=1 \
+ -v MESSAGE='Prefer rte_thread_(set_prefixed_name|create_internal_control) in lib & drivers' \
+ -f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
+ "$1" || res=1
+
# forbid inclusion of driver specific headers in apps and examples
awk -v FOLDERS='app examples' \
-v EXPRESSIONS='include.*_driver\\.h include.*_pmd\\.h' \
@@ -392,6 +392,39 @@ rte_thread_create_control(rte_thread_t *thread, const char *name,
return ret;
}
+static void
+add_internal_prefix(char *prefixed_name, const char *name, size_t size)
+{
+ size_t prefixlen;
+
+ /* Check RTE_THREAD_INTERNAL_NAME_SIZE definition. */
+ RTE_BUILD_BUG_ON(RTE_THREAD_INTERNAL_NAME_SIZE !=
+ RTE_THREAD_NAME_SIZE - sizeof(RTE_THREAD_INTERNAL_PREFIX) + 1);
+
+ prefixlen = strlen(RTE_THREAD_INTERNAL_PREFIX);
+ strlcpy(prefixed_name, RTE_THREAD_INTERNAL_PREFIX, size);
+ strlcpy(prefixed_name + prefixlen, name, size - prefixlen);
+}
+
+int
+rte_thread_create_internal_control(rte_thread_t *id, const char *name,
+ rte_thread_func func, void *arg)
+{
+ char prefixed_name[RTE_THREAD_NAME_SIZE];
+
+ add_internal_prefix(prefixed_name, name, sizeof(prefixed_name));
+ return rte_thread_create_control(id, prefixed_name, func, arg);
+}
+
+void
+rte_thread_set_prefixed_name(rte_thread_t id, const char *name)
+{
+ char prefixed_name[RTE_THREAD_NAME_SIZE];
+
+ add_internal_prefix(prefixed_name, name, sizeof(prefixed_name));
+ rte_thread_set_name(id, prefixed_name);
+}
+
int
rte_thread_register(void)
{
@@ -28,6 +28,11 @@ extern "C" {
/* Old definition, aliased for compatibility. */
#define RTE_MAX_THREAD_NAME_LEN RTE_THREAD_NAME_SIZE
+/** Thread name prefix automatically added to all internal threads. */
+#define RTE_THREAD_INTERNAL_PREFIX "dpdk-"
+/** Maximum internal thread name length (including '\0'). */
+#define RTE_THREAD_INTERNAL_NAME_SIZE 11
+
/**
* Thread id descriptor.
*/
@@ -112,7 +117,7 @@ int rte_thread_create(rte_thread_t *thread_id,
* @param thread_func
* Function to be executed by the new thread.
* @param arg
- * Argument passed to start_routine.
+ * Argument passed to thread_func.
* @return
* On success, returns 0; on error, it returns a negative value
* corresponding to the error number.
@@ -121,6 +126,35 @@ int
rte_thread_create_control(rte_thread_t *thread, const char *name,
rte_thread_func thread_func, void *arg);
+/**
+ * Create an internal control thread.
+ *
+ * Creates a control thread with the given name prefixed.
+ * If setting the name of the thread fails, the error is ignored and logged.
+ *
+ * The affinity of the new thread is based on the CPU affinity retrieved
+ * at the time rte_eal_init() was called, the EAL threads are then excluded.
+ *
+ * @param id
+ * Filled with the thread ID of the new created thread.
+ * @param name
+ * The name of the control thread.
+ * See RTE_THREAD_INTERNAL_NAME_SIZE for maximum length.
+ * The name of the driver or library should be first,
+ * then followed by a hyphen and more details.
+ * It will be prefixed with RTE_THREAD_INTERNAL_PREFIX by this function.
+ * @param func
+ * Function to be executed by the new thread.
+ * @param arg
+ * Argument passed to func.
+ * @return
+ * On success, returns 0; a negative value otherwise.
+ */
+__rte_internal
+int
+rte_thread_create_internal_control(rte_thread_t *id, const char *name,
+ rte_thread_func func, void *arg);
+
/**
* Waits for the thread identified by 'thread_id' to terminate
*
@@ -159,6 +193,7 @@ rte_thread_t rte_thread_self(void);
/**
* Set the name of the thread.
+ *
* This API is a noop if the underlying platform does not
* support setting the thread name or the platform-specific
* API used to set the thread name fails.
@@ -173,6 +208,26 @@ rte_thread_t rte_thread_self(void);
void
rte_thread_set_name(rte_thread_t thread_id, const char *thread_name);
+/**
+ * Set the name of an internal thread with the common prefix.
+ *
+ * This API is a noop if the underlying platform does not support
+ * setting the thread name, or if it fails.
+ *
+ * @param id
+ * The ID of the thread to set name.
+ *
+ * @param name
+ * The name to set after being prefixed.
+ * See RTE_THREAD_INTERNAL_NAME_SIZE for maximum length.
+ * The name of the driver or library should be first,
+ * then followed by a hyphen and more details.
+ * It will be prefixed with RTE_THREAD_INTERNAL_PREFIX by this function.
+ */
+__rte_internal
+void
+rte_thread_set_prefixed_name(rte_thread_t id, const char *name);
+
/**
* Check if 2 thread ids are equal.
*
@@ -462,4 +462,6 @@ INTERNAL {
rte_mem_map;
rte_mem_page_size;
rte_mem_unmap;
+ rte_thread_create_internal_control;
+ rte_thread_set_prefixed_name;
};