lib/trace_parser: reconstruct tracepoint arguments

Tracepoint arguments are now reconstructed when retrieving next trace
entry (possible from multiple buffers).  Similarly to previous patches,
the code is directly copied from the spdk_trace app.

Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Change-Id: Ie7594d381660ef31c286b5e124d2a6df3835111e
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9434
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Konrad Sztyber 2021-09-01 14:16:22 +02:00 committed by Tomasz Zawadzki
parent 65f01122b2
commit ffaec5f91c

View File

@ -32,6 +32,7 @@
*/
#include "spdk/stdinc.h"
#include "spdk/likely.h"
#include "spdk/log.h"
#include "spdk/trace_parser.h"
#include "spdk/util.h"
@ -61,6 +62,25 @@ public:
typedef std::map<entry_key, spdk_trace_entry *, compare_entry_key> entry_map;
struct argument_context {
spdk_trace_entry *entry;
spdk_trace_entry_buffer *buffer;
uint16_t lcore;
size_t offset;
argument_context(spdk_trace_entry *entry, uint16_t lcore) :
entry(entry), lcore(lcore)
{
buffer = reinterpret_cast<spdk_trace_entry_buffer *>(entry);
/* The first argument resides within the spdk_trace_entry structure, so the initial
* offset needs to be adjusted to the start of the spdk_trace_entry.args array
*/
offset = offsetof(spdk_trace_entry, args) -
offsetof(spdk_trace_entry_buffer, data);
}
};
struct spdk_trace_parser {
spdk_trace_parser(const spdk_trace_parser_opts *opts);
~spdk_trace_parser();
@ -70,6 +90,9 @@ struct spdk_trace_parser {
uint64_t tsc_offset() const { return _tsc_offset; }
bool next_entry(spdk_trace_parser_entry *entry);
private:
spdk_trace_entry_buffer *get_next_buffer(spdk_trace_entry_buffer *buf, uint16_t lcore);
bool build_arg(argument_context *argctx, const spdk_trace_argument *arg, int argid,
spdk_trace_parser_entry *pe);
void populate_events(spdk_trace_history *history, int num_entries);
bool init(const spdk_trace_parser_opts *opts);
void cleanup();
@ -82,15 +105,77 @@ private:
entry_map::iterator _iter;
};
bool
spdk_trace_parser::next_entry(spdk_trace_parser_entry *entry)
spdk_trace_entry_buffer *
spdk_trace_parser::get_next_buffer(spdk_trace_entry_buffer *buf, uint16_t lcore)
{
spdk_trace_history *history;
history = spdk_get_per_lcore_history(_histories, lcore);
assert(history);
if (spdk_unlikely(static_cast<void *>(buf) ==
static_cast<void *>(&history->entries[history->num_entries - 1]))) {
return reinterpret_cast<spdk_trace_entry_buffer *>(&history->entries[0]);
} else {
return buf + 1;
}
}
bool
spdk_trace_parser::build_arg(argument_context *argctx, const spdk_trace_argument *arg, int argid,
spdk_trace_parser_entry *pe)
{
spdk_trace_entry *entry = argctx->entry;
spdk_trace_entry_buffer *buffer = argctx->buffer;
size_t curlen, argoff;
argoff = 0;
while (argoff < arg->size) {
if (argctx->offset == sizeof(buffer->data)) {
buffer = get_next_buffer(buffer, argctx->lcore);
if (spdk_unlikely(buffer->tpoint_id != SPDK_TRACE_MAX_TPOINT_ID ||
buffer->tsc != entry->tsc)) {
return false;
}
argctx->offset = 0;
argctx->buffer = buffer;
}
curlen = spdk_min(sizeof(buffer->data) - argctx->offset, arg->size - argoff);
if (argoff < sizeof(pe->args[0])) {
memcpy(&pe->args[argid].string[argoff], &buffer->data[argctx->offset],
spdk_min(curlen, sizeof(pe->args[0]) - argoff));
}
argctx->offset += curlen;
argoff += curlen;
}
return true;
}
bool
spdk_trace_parser::next_entry(spdk_trace_parser_entry *pe)
{
spdk_trace_tpoint *tpoint;
spdk_trace_entry *entry;
if (_iter == _entries.end()) {
return false;
}
entry->entry = _iter->second;
entry->lcore = _iter->first.lcore;
pe->entry = entry = _iter->second;
pe->lcore = _iter->first.lcore;
tpoint = &_histories->flags.tpoint[entry->tpoint_id];
argument_context argctx(entry, pe->lcore);
for (uint8_t i = 0; i < tpoint->num_args; ++i) {
if (!build_arg(&argctx, &tpoint->args[i], i, pe)) {
SPDK_ERRLOG("Failed to parse tracepoint argument\n");
return false;
}
}
_iter++;
return true;