trace: implement register API

The consumers of trace API defines the tracepoint and registers
to eal. Internally these tracepoints will be stored in STAILQ
for future use. This patch implements the tracepoint
registration function.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Acked-by: David Marchand <david.marchand@redhat.com>
This commit is contained in:
Jerin Jacob 2020-04-23 00:33:20 +05:30 committed by David Marchand
parent 27db82c709
commit f58880682c
8 changed files with 210 additions and 2 deletions

View File

@ -199,6 +199,7 @@ M: Jerin Jacob <jerinj@marvell.com>
M: Sunil Kumar Kori <skori@marvell.com>
F: lib/librte_eal/include/rte_trace*.h
F: lib/librte_eal/common/eal_common_trace*.c
F: lib/librte_eal/common/eal_trace.h
Memory Allocation
M: Anatoly Burakov <anatoly.burakov@intel.com>

View File

@ -2,6 +2,107 @@
* Copyright(C) 2020 Marvell International Ltd.
*/
#include <rte_trace.h>
#include <rte_trace_point.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <rte_common.h>
#include <rte_errno.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
#include <rte_string_fns.h>
#include "eal_trace.h"
RTE_DEFINE_PER_LCORE(volatile int, trace_point_sz);
static RTE_DEFINE_PER_LCORE(char, ctf_field[TRACE_CTF_FIELD_SIZE]);
static RTE_DEFINE_PER_LCORE(int, ctf_count);
static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
static struct trace trace;
int
__rte_trace_point_register(rte_trace_point_t *handle, const char *name,
void (*register_fn)(void))
{
char *field = RTE_PER_LCORE(ctf_field);
struct trace_point *tp;
uint16_t sz;
/* Sanity checks of arguments */
if (name == NULL || register_fn == NULL || handle == NULL) {
trace_err("invalid arguments");
rte_errno = EINVAL;
goto fail;
}
/* Check the size of the trace point object */
RTE_PER_LCORE(trace_point_sz) = 0;
RTE_PER_LCORE(ctf_count) = 0;
register_fn();
if (RTE_PER_LCORE(trace_point_sz) == 0) {
trace_err("missing rte_trace_emit_header() in register fn");
rte_errno = EBADF;
goto fail;
}
/* Is size overflowed */
if (RTE_PER_LCORE(trace_point_sz) > UINT16_MAX) {
trace_err("trace point size overflowed");
rte_errno = ENOSPC;
goto fail;
}
/* Are we running out of space to store trace points? */
if (trace.nb_trace_points > UINT16_MAX) {
trace_err("trace point exceeds the max count");
rte_errno = ENOSPC;
goto fail;
}
/* Get the size of the trace point */
sz = RTE_PER_LCORE(trace_point_sz);
tp = calloc(1, sizeof(struct trace_point));
if (tp == NULL) {
trace_err("fail to allocate trace point memory");
rte_errno = ENOMEM;
goto fail;
}
/* Initialize the trace point */
if (rte_strscpy(tp->name, name, TRACE_POINT_NAME_SIZE) < 0) {
trace_err("name is too long");
rte_errno = E2BIG;
goto free;
}
/* Copy the field data for future use */
if (rte_strscpy(tp->ctf_field, field, TRACE_CTF_FIELD_SIZE) < 0) {
trace_err("CTF field size is too long");
rte_errno = E2BIG;
goto free;
}
/* Clear field memory for the next event */
memset(field, 0, TRACE_CTF_FIELD_SIZE);
/* Form the trace handle */
*handle = sz;
*handle |= trace.nb_trace_points << __RTE_TRACE_FIELD_ID_SHIFT;
trace.nb_trace_points++;
tp->handle = handle;
/* Add the trace point at tail */
STAILQ_INSERT_TAIL(&tp_list, tp, next);
__atomic_thread_fence(__ATOMIC_RELEASE);
/* All Good !!! */
return 0;
free:
free(tp);
fail:
if (trace.register_errno == 0)
trace.register_errno = rte_errno;
return -rte_errno;
}

View File

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2020 Marvell International Ltd.
*/
#ifndef __EAL_TRACE_H
#define __EAL_TRACE_H
#include <rte_trace.h>
#include <rte_trace_point.h>
#define trace_err(fmt, args...) \
RTE_LOG(ERR, EAL, "%s():%u " fmt "\n", __func__, __LINE__, ## args)
#define trace_crit(fmt, args...) \
RTE_LOG(CRIT, EAL, "%s():%u " fmt "\n", __func__, __LINE__, ## args)
#define TRACE_CTF_FIELD_SIZE 384
#define TRACE_POINT_NAME_SIZE 64
struct trace_point {
STAILQ_ENTRY(trace_point) next;
rte_trace_point_t *handle;
char name[TRACE_POINT_NAME_SIZE];
char ctf_field[TRACE_CTF_FIELD_SIZE];
};
struct trace {
int register_errno;
uint32_t nb_trace_points;
};
/* Trace point list functions */
STAILQ_HEAD(trace_point_head, trace_point);
#endif /* __EAL_TRACE_H */

View File

@ -42,6 +42,8 @@ headers += files(
'rte_time.h',
'rte_trace.h',
'rte_trace_point.h',
'rte_trace_point_provider.h',
'rte_trace_point_register.h',
'rte_uuid.h',
'rte_version.h',
'rte_vfio.h',

View File

@ -227,6 +227,32 @@ __rte_trace_point_fp_is_enabled(void)
#endif
}
/**
* @internal
*
* Helper function to register a dynamic tracepoint.
* Use RTE_TRACE_POINT_REGISTER macro for tracepoint registration.
*
* @param trace
* The tracepoint object created using RTE_TRACE_POINT_DEFINE.
* @param name
* The name of the tracepoint object.
* @param register_fn
* Trace registration function.
* @return
* - 0: Successfully registered the tracepoint.
* - <0: Failure to register the tracepoint.
*/
__rte_experimental
int __rte_trace_point_register(rte_trace_point_t *trace, const char *name,
void (*register_fn)(void));
#ifdef RTE_TRACE_POINT_REGISTER_SELECT
#include <rte_trace_point_register.h>
#else
#include <rte_trace_point_provider.h>
#endif
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2020 Marvell International Ltd.
*/
#ifndef _RTE_TRACE_POINT_H_
#error do not include this file directly, use <rte_trace_point.h> instead
#endif
#ifndef _RTE_TRACE_POINT_PROVIDER_H_
#define _RTE_TRACE_POINT_PROVIDER_H_
#define __RTE_TRACE_EVENT_HEADER_ID_SHIFT (48)
#define __RTE_TRACE_FIELD_SIZE_SHIFT 0
#define __RTE_TRACE_FIELD_SIZE_MASK (0xffffULL << __RTE_TRACE_FIELD_SIZE_SHIFT)
#define __RTE_TRACE_FIELD_ID_SHIFT (16)
#define __RTE_TRACE_FIELD_ID_MASK (0xffffULL << __RTE_TRACE_FIELD_ID_SHIFT)
#define __RTE_TRACE_FIELD_ENABLE_MASK (1ULL << 63)
#define __RTE_TRACE_FIELD_ENABLE_DISCARD (1ULL << 62)
#endif /* _RTE_TRACE_POINT_PROVIDER_H_ */

View File

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2020 Marvell International Ltd.
*/
#ifndef _RTE_TRACE_POINT_H_
#error do not include this file directly, use <rte_trace_point.h> instead
#endif
#ifndef _RTE_TRACE_POINT_REGISTER_H_
#define _RTE_TRACE_POINT_REGISTER_H_
#include <rte_per_lcore.h>
RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz);
#define RTE_TRACE_POINT_REGISTER(trace, name) \
__rte_trace_point_register(&__##trace, RTE_STR(name), \
(void (*)(void)) trace)
#endif /* _RTE_TRACE_POINT_REGISTER_H_ */

View File

@ -337,6 +337,8 @@ EXPERIMENTAL {
rte_thread_is_intr;
# added in 20.05
__rte_trace_point_register;
per_lcore_trace_point_sz;
rte_log_can_log;
rte_thread_getname;
};