Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1761250AbbKTU7m (ORCPT ); Fri, 20 Nov 2015 15:59:42 -0500 Received: from mx0a-00082601.pphosted.com ([67.231.145.42]:46643 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1761084AbbKTU5u (ORCPT ); Fri, 20 Nov 2015 15:57:50 -0500 From: Josef Bacik To: , , Subject: [PATCH 05/11] trace-cmd: allow for custom show and handle init Date: Fri, 20 Nov 2015 15:57:27 -0500 Message-ID: <1448053053-24188-6-git-send-email-jbacik@fb.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1448053053-24188-1-git-send-email-jbacik@fb.com> References: <1448053053-24188-1-git-send-email-jbacik@fb.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [192.168.52.123] X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2015-11-20_12:,, signatures=0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 12106 Lines: 378 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, Signed-off-by: Josef Bacik --- trace-cmd.h | 10 ++++++++++ trace-input.c | 24 ++++++++++++++++++++++++ trace-local.h | 11 ++++------- trace-profile.c | 10 +++++----- trace-read.c | 13 ++++++------- trace-record.c | 21 +++++++++------------ trace-stream.c | 12 ++++++------ 7 files changed, 64 insertions(+), 37 deletions(-) diff --git a/trace-cmd.h b/trace-cmd.h index 9a9ca30..7bf836f 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) { @@ -102,6 +103,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); @@ -186,6 +192,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 4b3aed8..8a131fc 100644 --- a/trace-input.c +++ b/trace-input.c @@ -37,6 +37,7 @@ #include #include "trace-cmd-local.h" +#include "trace-local.h" #include "kbuffer.h" #include "list.h" @@ -108,6 +109,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; @@ -3001,3 +3005,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 a1596e7..f21f665 100644 --- a/trace-local.h +++ b/trace-local.h @@ -77,8 +77,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); @@ -86,12 +84,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 0304e9b..7e41025 100644 --- a/trace-profile.c +++ b/trace-profile.c @@ -704,8 +704,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; @@ -714,6 +714,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) @@ -738,7 +739,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 */ @@ -757,8 +758,6 @@ int trace_profile_record(struct tracecmd_input *handle, free_record(stack_record); task->last_stack = NULL; } - - return 0; } static struct event_data * @@ -1233,6 +1232,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_or_die(sizeof(*h)); memset(h, 0, sizeof(*h)); h->next = handles; diff --git a/trace-read.c b/trace-read.c index 4459ea7..1a71629 100644 --- a/trace-read.c +++ b/trace-read.c @@ -739,22 +739,21 @@ 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; bool use_trace_clock; - 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) @@ -1159,7 +1158,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 7c471ab..f202d44 100644 --- a/trace-record.c +++ b/trace-record.c @@ -67,9 +67,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 use_tcp; @@ -564,7 +565,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; @@ -581,7 +581,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); } @@ -916,7 +916,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; @@ -927,7 +926,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 @@ -1085,12 +1084,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); } @@ -2576,7 +2574,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; @@ -2600,7 +2597,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); @@ -3869,8 +3866,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; @@ -4238,6 +4235,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; @@ -4351,8 +4349,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 9ebe65b..0dbeaf2 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; -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/