[dpdk-dev] [PATCH v1 05/32] eal/trace: add internal trace init and fini interface

Mattias Rönnblom mattias.ronnblom at ericsson.com
Thu Mar 19 11:35:41 CET 2020


On 2020-03-18 20:02, jerinj at marvell.com wrote:
> From: Jerin Jacob <jerinj at marvell.com>
>
> Define eal_trace_init() and eal_trace_fini() EAL interface
> functions that rte_eal_init() and rte_eal_cleanup() function can be
> use to initialize and finalize the trace subsystem.
> eal_trace_init() function will add the following
> functionality if trace is enabled through EAL command line param.
>
> - Test for trace registration failure.
> - Test for duplicate trace name registration
> - Generate UUID ver 4.
> - Create a trace directory
>
> Signed-off-by: Jerin Jacob <jerinj at marvell.com>
> Signed-off-by: Sunil Kumar Kori <skori at marvell.com>
> ---
>   lib/librte_eal/common/eal_common_trace.c      |  54 ++++++
>   .../common/eal_common_trace_utils.c           | 173 ++++++++++++++++++
>   lib/librte_eal/common/eal_trace.h             |  21 +++
>   lib/librte_eal/common/meson.build             |   1 +
>   lib/librte_eal/freebsd/eal/Makefile           |   1 +
>   lib/librte_eal/linux/eal/Makefile             |   1 +
>   6 files changed, 251 insertions(+)
>   create mode 100644 lib/librte_eal/common/eal_common_trace_utils.c
>
> diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
> index f8855e09b..abb221cf3 100644
> --- a/lib/librte_eal/common/eal_common_trace.c
> +++ b/lib/librte_eal/common/eal_common_trace.c
> @@ -22,6 +22,60 @@ RTE_DEFINE_PER_LCORE(int, ctf_count);
>   static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
>   static struct trace trace;
>   
> +struct trace*
> +trace_obj_get(void)
> +{
> +	return &trace;
> +}
> +
> +struct trace_point_head *
> +trace_list_head_get(void)
> +{
> +	return &tp_list;
> +}
> +
> +int
> +eal_trace_init(void)
> +{
> +	/* One of the Trace registration failed */
> +	if (trace.register_errno) {
> +		rte_errno = trace.register_errno;
> +		goto fail;
> +	}
> +
> +	if (rte_trace_global_is_disabled())
> +		return 0;
> +
> +	rte_spinlock_init(&trace.lock);
> +
> +	/* Is duplicate trace name registered */
> +	if (trace_has_duplicate_entry())
> +		goto fail;
> +
> +	/* Generate UUID ver 4 with total size of events and number of events */
> +	trace_uuid_generate();
> +
> +	/* Create trace directory */
> +	if (trace_mkdir())
> +		goto fail;
> +
> +
> +	rte_trace_global_mode_set(trace.mode);
> +
> +	return 0;
> +
> +fail:
> +	trace_err("failed to initialize trace [%s]", rte_strerror(rte_errno));
> +	return -rte_errno;
> +}
> +
> +void
> +eal_trace_fini(void)
> +{
> +	if (rte_trace_global_is_disabled())
> +		return;
> +}
> +
>   bool
>   rte_trace_global_is_enabled(void)
>   {
> diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
> new file mode 100644
> index 000000000..f7d59774c
> --- /dev/null
> +++ b/lib/librte_eal/common/eal_common_trace_utils.c
> @@ -0,0 +1,173 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2020 Marvell International Ltd.
> + */
> +
> +#include <fnmatch.h>
> +#include <pwd.h>
> +#include <sys/stat.h>
> +#include <time.h>
> +
> +#include <rte_common.h>
> +#include <rte_errno.h>
> +#include <rte_string_fns.h>
> +
> +#include "eal_filesystem.h"
> +#include "eal_trace.h"
> +
> +static bool
> +trace_entry_compare(const char *name)
> +{
> +	struct trace_point_head *tp_list = trace_list_head_get();
> +	struct trace_point *tp;
> +	int count = 0;
> +
> +	STAILQ_FOREACH(tp, tp_list, next) {
> +		if (strncmp(tp->name, name, TRACE_POINT_NAME_SIZE) == 0)
> +			count++;
> +		if (count > 1) {
> +			trace_err("found duplicate entry %s", name);
> +			rte_errno = EEXIST;
> +			return 1;

Maybe an assertion would be better here, especially since the caller 
doesn't seem to care about the fact the list is inconsistent.

Change 1 -> true.

> +		}
> +	}
> +	return 0;
return false;
> +}
> +
> +bool
> +trace_has_duplicate_entry(void)
> +{
> +	struct trace_point_head *tp_list = trace_list_head_get();
> +	struct trace_point *tp;
> +
> +	/* Is duplicate trace name registered */
> +	STAILQ_FOREACH(tp, tp_list, next)
> +		if (trace_entry_compare(tp->name))
> +			return true;
> +
> +	return false;
> +}
> +
> +void
> +trace_uuid_generate(void)
> +{
> +	struct trace_point_head *tp_list = trace_list_head_get();
> +	struct trace *trace = trace_obj_get();
> +	struct trace_point *tp;
> +	uint64_t sz_total = 0;
> +
> +	/* Go over the registered trace points to get total size of events */
> +	STAILQ_FOREACH(tp, tp_list, next) {
> +		const uint16_t sz = *tp->handle & __RTE_TRACE_FIELD_SIZE_MASK;
> +		sz_total += sz;
> +	}
> +
> +	rte_uuid_t uuid = RTE_UUID_INIT(sz_total, trace->nb_trace_points,
> +		0x4370, 0x8f50, 0x222ddd514176ULL);
> +	rte_uuid_copy(trace->uuid, uuid);
> +}
> +
> +static int
> +trace_session_name_generate(char *trace_dir)
> +{
> +	struct tm *tm_result;
> +	time_t tm;
> +	int rc;
> +
> +	tm = time(NULL);
> +	if ((int)tm == -1)
> +		goto fail;
> +
> +	tm_result = localtime(&tm);
> +	if (tm_result == NULL)
> +		goto fail;
> +
> +	rc = rte_strscpy(trace_dir,
> +			 eal_get_hugefile_prefix(), TRACE_PREFIX_LEN);
> +	if (rc == -E2BIG)
> +		rc = TRACE_PREFIX_LEN;
> +	trace_dir[rc++] = '-';
> +
> +	rc = strftime(trace_dir + rc, TRACE_DIR_STR_LEN - rc,
> +			"%Y-%m-%d-%p-%I-%M-%S", tm_result);
> +	if (rc == 0)
> +		goto fail;
> +
> +	return rc;
> +fail:
> +	rte_errno = errno;
> +	return -rte_errno;
> +}
> +
> +static int
> +trace_dir_default_path_get(char *dir_path)
> +{
> +	struct trace *trace = trace_obj_get();
> +	uint32_t size = sizeof(trace->dir);
> +	struct passwd *pwd;
> +	char *home_dir;
> +
> +	/* First check for shell environment variable */
> +	home_dir = getenv("HOME");
In case of the application being started with 'sudo', $HOME will not be 
"/root", but rather the original user. This sounds like a bug to me.
> +	if (home_dir == NULL) {
> +		/* Fallback to password file entry */
> +		pwd = getpwuid(getuid());
> +		if (pwd == NULL)
> +			return -EINVAL;
> +
> +		home_dir = pwd->pw_dir;
> +	}
> +
> +	/* Append dpdk-traces to directory */
> +	if (snprintf(dir_path, size, "%s/dpdk-traces/", home_dir) < 0)
> +		return -ENAMETOOLONG;
> +
> +	return 0;
> +}
> +
> +int
> +trace_mkdir(void)
> +{
> +	struct trace *trace = trace_obj_get();
> +	char session[TRACE_DIR_STR_LEN];
> +	char *dir_path;
> +	int rc;
> +
> +	if (!trace->dir_offset) {
> +		dir_path = (char *)calloc(1, sizeof(trace->dir));
calloc() returns a void pointer, so no need to cast it.
> +		if (dir_path == NULL) {
> +			trace_err("fail to allocate memory\n");
> +			return -ENOMEM;
> +		}
> +
> +		rc = trace_dir_default_path_get(dir_path);
> +		if (rc < 0) {
> +			trace_err("fail to get default path\n");
> +			free(dir_path);
> +			return rc;
> +		}
> +
> +	}
> +
> +	/* Create the path if it t exist, no "mkdir -p" available here */
> +	rc = mkdir(trace->dir, 0700);
> +	if (rc < 0 && errno != EEXIST) {
> +		trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno));
> +		rte_errno = errno;
> +		return -rte_errno;
> +	}
> +
> +	rc = trace_session_name_generate(session);
> +	if (rc < 0)
> +		return rc;
> +
> +	rc = mkdir(trace->dir, 0700);
> +	if (rc < 0) {
> +		trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno));
> +		rte_errno = errno;
> +		return -rte_errno;
> +	}
> +
> +	RTE_LOG(INFO, EAL, "Trace dir: %s\n", trace->dir);
> +	return 0;

Is dir_path leaked? I can't find a free(), except in one of the error cases.

> +}
> +
> diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
> index 9f90a5d17..10c2f03ac 100644
> --- a/lib/librte_eal/common/eal_trace.h
> +++ b/lib/librte_eal/common/eal_trace.h
> @@ -5,7 +5,9 @@
>   #ifndef __EAL_TRACE_H
>   #define __EAL_TRACE_H
>   
> +#include <rte_spinlock.h>
>   #include <rte_trace.h>
> +#include <rte_uuid.h>
>   
>   #define trace_err(fmt, args...)\
>   	RTE_LOG(ERR, EAL, "%s():%u " fmt "\n",\
> @@ -15,6 +17,8 @@
>   	RTE_LOG(CRIT, EAL, "%s():%u " fmt "\n",\
>   		__func__, __LINE__, ## args)
>   
> +#define TRACE_PREFIX_LEN 12
> +#define TRACE_DIR_STR_LEN (sizeof("YYYY-mm-dd-AM-HH-MM-SS") + TRACE_PREFIX_LEN)
>   #define TRACE_CTF_FIELD_SIZE 384
>   #define TRACE_POINT_NAME_SIZE 64
>   
> @@ -26,11 +30,15 @@ struct trace_point {
>   };
>   
>   struct trace {
> +	char dir[PATH_MAX];
> +	int dir_offset;
>   	int register_errno;
>   	bool global_status;
>   	enum rte_trace_mode_e mode;
> +	rte_uuid_t uuid;
>   	uint32_t level;
>   	uint32_t nb_trace_points;
> +	rte_spinlock_t lock;
>   };
>   
>   /* Helper functions */
> @@ -41,7 +49,20 @@ trace_id_get(rte_trace_t trace)
>   		__RTE_TRACE_FIELD_ID_SHIFT;
>   }
>   
> +/* Trace object functions */
> +struct trace *trace_obj_get(void);
> +
>   /* Trace point list functions */
>   STAILQ_HEAD(trace_point_head, trace_point);
> +struct trace_point_head *trace_list_head_get(void);
> +
> +/* Util functions */
> +bool trace_has_duplicate_entry(void);
> +void trace_uuid_generate(void);
> +int trace_mkdir(void);
> +
> +/* EAL interface */
> +int eal_trace_init(void);
> +void eal_trace_fini(void);
>   
>   #endif /* __EAL_TRACE_H */
> diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
> index 88c14ebe5..716a255d2 100644
> --- a/lib/librte_eal/common/meson.build
> +++ b/lib/librte_eal/common/meson.build
> @@ -29,6 +29,7 @@ common_sources = files(
>   	'eal_common_thread.c',
>   	'eal_common_timer.c',
>   	'eal_common_trace.c',
> +	'eal_common_trace_utils.c',
>   	'eal_common_uuid.c',
>   	'hotplug_mp.c',
>   	'malloc_elem.c',
> diff --git a/lib/librte_eal/freebsd/eal/Makefile b/lib/librte_eal/freebsd/eal/Makefile
> index b2fcc4212..8c444da02 100644
> --- a/lib/librte_eal/freebsd/eal/Makefile
> +++ b/lib/librte_eal/freebsd/eal/Makefile
> @@ -61,6 +61,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace.c
> +SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_utils.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += malloc_elem.c
> diff --git a/lib/librte_eal/linux/eal/Makefile b/lib/librte_eal/linux/eal/Makefile
> index 95470d3bb..bd9993e58 100644
> --- a/lib/librte_eal/linux/eal/Makefile
> +++ b/lib/librte_eal/linux/eal/Makefile
> @@ -69,6 +69,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace.c
> +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_utils.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += malloc_elem.c




More information about the dev mailing list