aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2015-11-20 15:57:27 -0500
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2017-04-26 10:49:42 -0400
commitf2b32ffc2844858ffb21864beaa2d95e3f4b5fa9 (patch)
tree1c2cf84c9f55781757e0f493b2020ebc96f43035
parent7426a21e93d796c43846ae55e9761ef6f107a673 (diff)
downloadtrace-cmd-f2b32ffc2844858ffb21864beaa2d95e3f4b5fa9.tar.gz
trace-cmd: allow for custom show and handle init
External applications that need to hook into the streaming infrastructure need a way to have the handle init'ed in a specific way and need a way to provide their own read function so they can intercept events. This patch adds the neccessary definitions and hooks. Thanks, Link: http://lkml.kernel.org/r/1448053053-24188-6-git-send-email-jbacik@fb.com Signed-off-by: Josef Bacik <jbacik@fb.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-cmd.h10
-rw-r--r--trace-input.c23
-rw-r--r--trace-local.h11
-rw-r--r--trace-profile.c12
-rw-r--r--trace-read.c14
-rw-r--r--trace-record.c21
-rw-r--r--trace-stream.c12
7 files changed, 65 insertions, 38 deletions
diff --git a/trace-cmd.h b/trace-cmd.h
index e427d903..6a229100 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -61,6 +61,7 @@ void free_record(struct pevent_record *record);
struct tracecmd_input;
struct tracecmd_output;
struct tracecmd_recorder;
+struct hook_list;
static inline int tracecmd_host_bigendian(void)
{
@@ -103,6 +104,11 @@ struct tracecmd_ftrace {
int long_size;
};
+typedef void (*tracecmd_show_data_func)(struct tracecmd_input *handle,
+ struct pevent_record *record);
+typedef void (*tracecmd_handle_init_func)(struct tracecmd_input *handle,
+ struct hook_list *hook, int global);
+
struct tracecmd_input *tracecmd_alloc(const char *file);
struct tracecmd_input *tracecmd_alloc_fd(int fd);
struct tracecmd_input *tracecmd_open(const char *file);
@@ -193,6 +199,10 @@ tracecmd_get_cursor(struct tracecmd_input *handle, int cpu);
int tracecmd_ftrace_overrides(struct tracecmd_input *handle, struct tracecmd_ftrace *finfo);
struct pevent *tracecmd_get_pevent(struct tracecmd_input *handle);
bool tracecmd_get_use_trace_clock(struct tracecmd_input *handle);
+tracecmd_show_data_func
+tracecmd_get_show_data_func(struct tracecmd_input *handle);
+void tracecmd_set_show_data_func(struct tracecmd_input *handle,
+ tracecmd_show_data_func func);
char *tracecmd_get_tracing_file(const char *name);
void tracecmd_put_tracing_file(char *name);
diff --git a/trace-input.c b/trace-input.c
index e7d447b4..b90b31e4 100644
--- a/trace-input.c
+++ b/trace-input.c
@@ -125,6 +125,9 @@ struct tracecmd_input {
size_t ftrace_files_start;
size_t event_files_start;
size_t total_file_size;
+
+ /* For custom profilers. */
+ tracecmd_show_data_func show_data_func;
};
__thread struct tracecmd_input *tracecmd_curr_thread_handle;
@@ -3203,3 +3206,23 @@ bool tracecmd_get_use_trace_clock(struct tracecmd_input *handle)
{
return handle->use_trace_clock;
}
+
+/**
+ * tracecmd_get_show_data_func - return the show data func
+ * @handle: input handle for the trace.dat file
+ */
+tracecmd_show_data_func
+tracecmd_get_show_data_func(struct tracecmd_input *handle)
+{
+ return handle->show_data_func;
+}
+
+/**
+ * tracecmd_set_show_data_func - set the show data func
+ * @handle: input handle for the trace.dat file
+ */
+void tracecmd_set_show_data_func(struct tracecmd_input *handle,
+ tracecmd_show_data_func func)
+{
+ handle->show_data_func = func;
+}
diff --git a/trace-local.h b/trace-local.h
index aa032218..46aa9798 100644
--- a/trace-local.h
+++ b/trace-local.h
@@ -79,8 +79,6 @@ void trace_stat(int argc, char **argv);
struct hook_list;
-int trace_profile_record(struct tracecmd_input *handle,
- struct pevent_record *record, int cpu);
void trace_init_profile(struct tracecmd_input *handle, struct hook_list *hooks,
int global);
int trace_profile(void);
@@ -88,12 +86,11 @@ void trace_profile_set_merge_like_comms(void);
struct tracecmd_input *
trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
- int profile, struct hook_list *hooks, int global);
-int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv,
- int profile);
+ struct hook_list *hooks,
+ tracecmd_handle_init_func handle_init, int global);
+int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv);
-void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record,
- int profile);
+void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record);
/* --- event interation --- */
diff --git a/trace-profile.c b/trace-profile.c
index 507a0c35..0af27cda 100644
--- a/trace-profile.c
+++ b/trace-profile.c
@@ -745,8 +745,8 @@ find_event_data(struct handle_data *h, int id)
return NULL;
}
-int trace_profile_record(struct tracecmd_input *handle,
- struct pevent_record *record, int cpu)
+static void trace_profile_record(struct tracecmd_input *handle,
+ struct pevent_record *record)
{
static struct handle_data *last_handle;
struct pevent_record *stack_record;
@@ -755,6 +755,7 @@ int trace_profile_record(struct tracecmd_input *handle,
struct handle_data *h;
struct pevent *pevent;
unsigned long long pid;
+ int cpu = record->cpu;
int id;
if (last_handle && last_handle->handle == handle)
@@ -779,7 +780,7 @@ int trace_profile_record(struct tracecmd_input *handle,
event_data = find_event_data(h, id);
if (!event_data)
- return -1;
+ return;
/* Get this current PID */
@@ -787,7 +788,7 @@ int trace_profile_record(struct tracecmd_input *handle,
task = find_task(h, pid);
if (!task)
- return -1;
+ return;
stack_record = task->last_stack;
if (event_data->handle_event)
@@ -800,8 +801,6 @@ int trace_profile_record(struct tracecmd_input *handle,
free_record(stack_record);
task->last_stack = NULL;
}
-
- return 0;
}
static struct event_data *
@@ -1302,6 +1301,7 @@ void trace_init_profile(struct tracecmd_input *handle, struct hook_list *hook,
int ret;
int i;
+ tracecmd_set_show_data_func(handle, trace_profile_record);
h = malloc(sizeof(*h));
if (!h) {
warning("Could not allocate handle");
diff --git a/trace-read.c b/trace-read.c
index 40055a3f..685a81be 100644
--- a/trace-read.c
+++ b/trace-read.c
@@ -761,9 +761,9 @@ static void finish_wakeup(void)
trace_hash_free(&wakeup_hash);
}
-void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record,
- int profile)
+void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record)
{
+ tracecmd_show_data_func func = tracecmd_get_show_data_func(handle);
struct pevent *pevent;
struct trace_seq s;
int cpu = record->cpu;
@@ -772,15 +772,15 @@ void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record
unsigned long long diff_ts;
char buf[50];
- pevent = tracecmd_get_pevent(handle);
-
test_save(record, cpu);
- if (profile) {
- trace_profile_record(handle, record, cpu);
+ if (func) {
+ func(handle, record);
return;
}
+ pevent = tracecmd_get_pevent(handle);
+
trace_seq_init(&s);
if (record->missed_events > 0)
trace_seq_printf(&s, "CPU:%d [%lld EVENTS DROPPED]\n",
@@ -1219,7 +1219,7 @@ static void read_data_info(struct list_head *handle_list, enum output_type otype
}
if (last_record) {
print_handle_file(last_handle);
- trace_show_data(last_handle->handle, last_record, profile);
+ trace_show_data(last_handle->handle, last_record);
free_handle_record(last_handle);
}
} while (last_record);
diff --git a/trace-record.c b/trace-record.c
index 84a67078..bd60892a 100644
--- a/trace-record.c
+++ b/trace-record.c
@@ -66,9 +66,10 @@ enum trace_type {
TRACE_TYPE_START = (1 << 1),
TRACE_TYPE_STREAM = (1 << 2),
TRACE_TYPE_EXTRACT = (1 << 3),
- TRACE_TYPE_PROFILE = (1 << 4) | TRACE_TYPE_STREAM,
};
+static tracecmd_handle_init_func handle_init = NULL;
+
static int rt_prio;
static int keep;
@@ -603,7 +604,6 @@ static void delete_thread_data(void)
static void stop_threads(enum trace_type type)
{
struct timeval tv = { 0, 0 };
- int profile = (type & TRACE_TYPE_PROFILE) == TRACE_TYPE_PROFILE;
int ret;
int i;
@@ -620,7 +620,7 @@ static void stop_threads(enum trace_type type)
/* Flush out the pipes */
if (type & TRACE_TYPE_STREAM) {
do {
- ret = trace_stream_read(pids, recorder_threads, &tv, profile);
+ ret = trace_stream_read(pids, recorder_threads, &tv);
} while (ret > 0);
}
@@ -990,7 +990,6 @@ static pid_t trace_waitpid(enum trace_type type, pid_t pid, int *status, int opt
{
struct timeval tv = { 1, 0 };
int ret;
- int profile = (type & TRACE_TYPE_PROFILE) == TRACE_TYPE_PROFILE;
if (type & TRACE_TYPE_STREAM)
options |= WNOHANG;
@@ -1001,7 +1000,7 @@ static pid_t trace_waitpid(enum trace_type type, pid_t pid, int *status, int opt
return ret;
if (type & TRACE_TYPE_STREAM)
- trace_stream_read(pids, recorder_threads, &tv, profile);
+ trace_stream_read(pids, recorder_threads, &tv);
} while (1);
}
#ifndef NO_PTRACE
@@ -1182,12 +1181,11 @@ static inline void ptrace_attach(int pid) { }
static void trace_or_sleep(enum trace_type type)
{
struct timeval tv = { 1 , 0 };
- int profile = (type & TRACE_TYPE_PROFILE) == TRACE_TYPE_PROFILE;
if (do_ptrace && filter_pid >= 0)
ptrace_wait(type, filter_pid);
else if (type & TRACE_TYPE_STREAM)
- trace_stream_read(pids, recorder_threads, &tv, profile);
+ trace_stream_read(pids, recorder_threads, &tv);
else
sleep(10);
}
@@ -2851,7 +2849,6 @@ static void finish_network(void)
static void start_threads(enum trace_type type, int global)
{
- int profile = (type & TRACE_TYPE_PROFILE) == TRACE_TYPE_PROFILE;
struct buffer_instance *instance;
int *brass = NULL;
int i = 0;
@@ -2877,7 +2874,7 @@ static void start_threads(enum trace_type type, int global)
die("pipe");
pids[i].stream = trace_stream_init(instance, x,
brass[0], cpu_count,
- profile, hooks,
+ hooks, handle_init,
global);
if (!pids[i].stream)
die("Creating stream for %d", i);
@@ -4213,8 +4210,8 @@ void trace_record (int argc, char **argv)
else if ((stream = strcmp(argv[1], "stream") == 0))
; /* do nothing */
else if ((profile = strcmp(argv[1], "profile") == 0)) {
+ handle_init = trace_init_profile;
events = 1;
-
} else if (strcmp(argv[1], "stop") == 0) {
for (;;) {
int c;
@@ -4608,6 +4605,7 @@ void trace_record (int argc, char **argv)
recorder_flags |= TRACECMD_RECORD_NOSPLICE;
break;
case OPT_profile:
+ handle_init = trace_init_profile;
instance->profile = 1;
events = 1;
break;
@@ -4738,8 +4736,7 @@ void trace_record (int argc, char **argv)
else if (extract)
type = TRACE_TYPE_EXTRACT;
else if (profile)
- /* PROFILE includes the STREAM bit */
- type = TRACE_TYPE_PROFILE;
+ type = TRACE_TYPE_STREAM;
else
type = TRACE_TYPE_START;
diff --git a/trace-stream.c b/trace-stream.c
index 9ebe65b7..0dbeaf2b 100644
--- a/trace-stream.c
+++ b/trace-stream.c
@@ -35,7 +35,8 @@
*/
struct tracecmd_input *
trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
- int profile, struct hook_list *hooks, int global)
+ struct hook_list *hooks,
+ tracecmd_handle_init_func handle_init, int global)
{
struct tracecmd_input *trace_input;
struct tracecmd_output *trace_output;
@@ -75,8 +76,8 @@ trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
if (tracecmd_read_headers(trace_input) < 0)
goto fail_free_input;
- if (profile)
- trace_init_profile(trace_input, hooks, global);
+ if (handle_init)
+ handle_init(trace_input, hooks, global);
make_pipe:
/* Do not block on this pipe */
@@ -98,8 +99,7 @@ trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
return NULL;
}
-int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv,
- int profile)
+int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv)
{
struct pevent_record *record;
struct pid_record_data *pid;
@@ -127,7 +127,7 @@ int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval
last_pid = pid;
}
if (last_pid) {
- trace_show_data(last_pid->instance->handle, last_pid->record, profile);
+ trace_show_data(last_pid->instance->handle, last_pid->record);
free_record(last_pid->record);
last_pid->record = NULL;
return 1;