Skip to content

Commit

Permalink
trace: implement provider payload
Browse files Browse the repository at this point in the history
The trace function payloads such as rte_trace_point_emit_* have
dual functions. The first to emit the payload for the registration
function and the second one to act as trace mem emitters a.k.a
provider payload.

When it is used as provider payload, those function copy the trace
field to trace memory based on the tracing mode.

Added payload definitions under ALLOW_EXPERIMENTAL_API define
to allow the existing applications to compile without enabling
experimental APIs.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
Acked-by: David Marchand <david.marchand@redhat.com>
  • Loading branch information
jerinjacobk authored and david-marchand committed Apr 23, 2020
1 parent 0cd4ea0 commit 032a7e5
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
18 changes: 18 additions & 0 deletions lib/librte_eal/include/rte_trace_point.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,24 @@ int __rte_trace_point_register(rte_trace_point_t *trace, const char *name,
#include <rte_trace_point_provider.h>
#endif

#ifndef __DOXYGEN__

#define rte_trace_point_emit_u64(in) __rte_trace_point_emit(in, uint64_t)
#define rte_trace_point_emit_i64(in) __rte_trace_point_emit(in, int64_t)
#define rte_trace_point_emit_u32(in) __rte_trace_point_emit(in, uint32_t)
#define rte_trace_point_emit_i32(in) __rte_trace_point_emit(in, int32_t)
#define rte_trace_point_emit_u16(in) __rte_trace_point_emit(in, uint16_t)
#define rte_trace_point_emit_i16(in) __rte_trace_point_emit(in, int16_t)
#define rte_trace_point_emit_u8(in) __rte_trace_point_emit(in, uint8_t)
#define rte_trace_point_emit_i8(in) __rte_trace_point_emit(in, int8_t)
#define rte_trace_point_emit_int(in) __rte_trace_point_emit(in, int32_t)
#define rte_trace_point_emit_long(in) __rte_trace_point_emit(in, long)
#define rte_trace_point_emit_float(in) __rte_trace_point_emit(in, float)
#define rte_trace_point_emit_double(in) __rte_trace_point_emit(in, double)
#define rte_trace_point_emit_ptr(in) __rte_trace_point_emit(in, uintptr_t)

#endif

#ifdef __cplusplus
}
#endif
Expand Down
90 changes: 90 additions & 0 deletions lib/librte_eal/include/rte_trace_point_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#ifndef _RTE_TRACE_POINT_PROVIDER_H_
#define _RTE_TRACE_POINT_PROVIDER_H_

#ifdef ALLOW_EXPERIMENTAL_API

#include <rte_branch_prediction.h>
#include <rte_cycles.h>
#include <rte_per_lcore.h>
#include <rte_string_fns.h>
#include <rte_uuid.h>
Expand Down Expand Up @@ -38,4 +42,90 @@ struct __rte_trace_header {

RTE_DECLARE_PER_LCORE(void *, trace_mem);

static __rte_always_inline void *
__rte_trace_mem_get(uint64_t in)
{
struct __rte_trace_header *trace = RTE_PER_LCORE(trace_mem);
const uint16_t sz = in & __RTE_TRACE_FIELD_SIZE_MASK;

/* Trace memory is not initialized for this thread */
if (unlikely(trace == NULL)) {
__rte_trace_mem_per_thread_alloc();
trace = RTE_PER_LCORE(trace_mem);
if (unlikely(trace == NULL))
return NULL;
}
/* Check the wrap around case */
uint32_t offset = trace->offset;
if (unlikely((offset + sz) >= trace->len)) {
/* Disable the trace event if it in DISCARD mode */
if (unlikely(in & __RTE_TRACE_FIELD_ENABLE_DISCARD))
return NULL;

offset = 0;
}
/* Align to event header size */
offset = RTE_ALIGN_CEIL(offset, __RTE_TRACE_EVENT_HEADER_SZ);
void *mem = RTE_PTR_ADD(&trace->mem[0], offset);
offset += sz;
trace->offset = offset;

return mem;
}

static __rte_always_inline void *
__rte_trace_point_emit_ev_header(void *mem, uint64_t in)
{
uint64_t val;

/* Event header [63:0] = id [63:48] | timestamp [47:0] */
val = rte_get_tsc_cycles() &
~(0xffffULL << __RTE_TRACE_EVENT_HEADER_ID_SHIFT);
val |= ((in & __RTE_TRACE_FIELD_ID_MASK) <<
(__RTE_TRACE_EVENT_HEADER_ID_SHIFT - __RTE_TRACE_FIELD_ID_SHIFT));

*(uint64_t *)mem = val;
return RTE_PTR_ADD(mem, __RTE_TRACE_EVENT_HEADER_SZ);
}

#define __rte_trace_point_emit_header_generic(t) \
void *mem; \
do { \
const uint64_t val = __atomic_load_n(t, __ATOMIC_ACQUIRE); \
if (likely(!(val & __RTE_TRACE_FIELD_ENABLE_MASK))) \
return; \
mem = __rte_trace_mem_get(val); \
if (unlikely(mem == NULL)) \
return; \
mem = __rte_trace_point_emit_ev_header(mem, val); \
} while (0)

#define __rte_trace_point_emit_header_fp(t) \
if (!__rte_trace_point_fp_is_enabled()) \
return; \
__rte_trace_point_emit_header_generic(t)

#define __rte_trace_point_emit(in, type) \
do { \
memcpy(mem, &(in), sizeof(in)); \
mem = RTE_PTR_ADD(mem, sizeof(in)); \
} while (0)

#define rte_trace_point_emit_string(in) \
do { \
if (unlikely(in == NULL)) \
return; \
rte_strscpy(mem, in, __RTE_TRACE_EMIT_STRING_LEN_MAX); \
mem = RTE_PTR_ADD(mem, __RTE_TRACE_EMIT_STRING_LEN_MAX); \
} while (0)

#else

#define __rte_trace_point_emit_header_generic(t) RTE_SET_USED(t)
#define __rte_trace_point_emit_header_fp(t) RTE_SET_USED(t)
#define __rte_trace_point_emit(in, type) RTE_SET_USED(in)
#define rte_trace_point_emit_string(in) RTE_SET_USED(in)

#endif

#endif /* _RTE_TRACE_POINT_PROVIDER_H_ */

0 comments on commit 032a7e5

Please sign in to comment.