Skip to content

Commit

Permalink
tracing: Allow events to share their print functions
Browse files Browse the repository at this point in the history
Multiple events may use the same method to print their data.
Instead of having all events have a pointer to their print funtions,
the trace_event structure now points to a trace_event_functions structure
that will hold the way to print ouf the event.

The event itself is now passed to the print function to let the print
function know what kind of event it should print.

This opens the door to consolidating the way several events print
their output.

   text	   data	    bss	    dec	    hex	filename
4913961	1088356	 861512	6863829	 68bbd5	vmlinux.orig
4900382	1048964	 861512	6810858	 67ecea	vmlinux.init
4900446	1049028	 861512	6810986	 67ed6a	vmlinux.preprint

This change slightly increases the size but is needed for the next change.

v3: Fix the branch tracer events to handle this change.

v2: Fix the new function graph tracer event calls to handle this change.

Acked-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Acked-by: Masami Hiramatsu <mhiramat@redhat.com>
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
  • Loading branch information
Steven Rostedt authored and Steven Rostedt committed May 14, 2010
1 parent 0405ab8 commit a9a5776
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 92 deletions.
17 changes: 12 additions & 5 deletions include/linux/ftrace_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,25 @@ struct trace_iterator {
};


struct trace_event;

typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter,
int flags);
struct trace_event {
struct hlist_node node;
struct list_head list;
int type;
int flags, struct trace_event *event);

struct trace_event_functions {
trace_print_func trace;
trace_print_func raw;
trace_print_func hex;
trace_print_func binary;
};

struct trace_event {
struct hlist_node node;
struct list_head list;
int type;
struct trace_event_functions *funcs;
};

extern int register_ftrace_event(struct trace_event *event);
extern int unregister_ftrace_event(struct trace_event *event);

Expand Down
10 changes: 8 additions & 2 deletions include/linux/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,12 @@ extern struct ftrace_event_class event_class_syscall_exit;
static struct syscall_metadata __syscall_meta_##sname; \
static struct ftrace_event_call \
__attribute__((__aligned__(4))) event_enter_##sname; \
static struct trace_event enter_syscall_print_##sname = { \
static struct trace_event_functions enter_syscall_print_funcs_##sname = { \
.trace = print_syscall_enter, \
}; \
static struct trace_event enter_syscall_print_##sname = { \
.funcs = &enter_syscall_print_funcs_##sname, \
}; \
static struct ftrace_event_call __used \
__attribute__((__aligned__(4))) \
__attribute__((section("_ftrace_events"))) \
Expand All @@ -142,9 +145,12 @@ extern struct ftrace_event_class event_class_syscall_exit;
static struct syscall_metadata __syscall_meta_##sname; \
static struct ftrace_event_call \
__attribute__((__aligned__(4))) event_exit_##sname; \
static struct trace_event exit_syscall_print_##sname = { \
static struct trace_event_functions exit_syscall_print_funcs_##sname = { \
.trace = print_syscall_exit, \
}; \
static struct trace_event exit_syscall_print_##sname = { \
.funcs = &exit_syscall_print_funcs_##sname, \
}; \
static struct ftrace_event_call __used \
__attribute__((__aligned__(4))) \
__attribute__((section("_ftrace_events"))) \
Expand Down
13 changes: 8 additions & 5 deletions include/trace/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ ftrace_raw_output_id_##call(int event_id, const char *name, \
#undef DEFINE_EVENT
#define DEFINE_EVENT(template, name, proto, args) \
static notrace enum print_line_t \
ftrace_raw_output_##name(struct trace_iterator *iter, int flags) \
ftrace_raw_output_##name(struct trace_iterator *iter, int flags, \
struct trace_event *event) \
{ \
return ftrace_raw_output_id_##template(event_##name.id, \
#name, iter, flags); \
Expand All @@ -248,7 +249,8 @@ ftrace_raw_output_##name(struct trace_iterator *iter, int flags) \
#undef DEFINE_EVENT_PRINT
#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \
static notrace enum print_line_t \
ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
ftrace_raw_output_##call(struct trace_iterator *iter, int flags, \
struct trace_event *event) \
{ \
struct trace_seq *s = &iter->seq; \
struct ftrace_raw_##template *field; \
Expand Down Expand Up @@ -531,11 +533,12 @@ ftrace_raw_event_##call(void *__data, proto) \

#undef DEFINE_EVENT
#define DEFINE_EVENT(template, call, proto, args) \
\
static struct trace_event ftrace_event_type_##call = { \
static struct trace_event_functions ftrace_event_type_funcs_##call = { \
.trace = ftrace_raw_output_##call, \
}; \
\
static struct trace_event ftrace_event_type_##call = { \
.funcs = &ftrace_event_type_funcs_##call, \
}; \
static inline void ftrace_test_probe_##call(void) \
{ \
check_trace_callback_type_##call(ftrace_raw_event_##template); \
Expand Down
6 changes: 4 additions & 2 deletions include/trace/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ extern int reg_event_syscall_exit(struct ftrace_event_call *call);
extern void unreg_event_syscall_exit(struct ftrace_event_call *call);
extern int
ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s);
enum print_line_t print_syscall_enter(struct trace_iterator *iter, int flags);
enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags);
enum print_line_t print_syscall_enter(struct trace_iterator *iter, int flags,
struct trace_event *event);
enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags,
struct trace_event *event);
#endif

#ifdef CONFIG_PERF_EVENTS
Expand Down
13 changes: 9 additions & 4 deletions kernel/trace/blktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1336,7 +1336,7 @@ static enum print_line_t print_one_line(struct trace_iterator *iter,
}

static enum print_line_t blk_trace_event_print(struct trace_iterator *iter,
int flags)
int flags, struct trace_event *event)
{
return print_one_line(iter, false);
}
Expand All @@ -1358,7 +1358,8 @@ static int blk_trace_synthesize_old_trace(struct trace_iterator *iter)
}

static enum print_line_t
blk_trace_event_print_binary(struct trace_iterator *iter, int flags)
blk_trace_event_print_binary(struct trace_iterator *iter, int flags,
struct trace_event *event)
{
return blk_trace_synthesize_old_trace(iter) ?
TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE;
Expand Down Expand Up @@ -1396,12 +1397,16 @@ static struct tracer blk_tracer __read_mostly = {
.set_flag = blk_tracer_set_flag,
};

static struct trace_event trace_blk_event = {
.type = TRACE_BLK,
static struct trace_event_functions trace_blk_event_funcs = {
.trace = blk_trace_event_print,
.binary = blk_trace_event_print_binary,
};

static struct trace_event trace_blk_event = {
.type = TRACE_BLK,
.funcs = &trace_blk_event_funcs,
};

static int __init init_blk_tracer(void)
{
if (!register_ftrace_event(&trace_blk_event)) {
Expand Down
28 changes: 20 additions & 8 deletions kernel/trace/kmemtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ struct kmemtrace_user_event_alloc {
};

static enum print_line_t
kmemtrace_print_alloc(struct trace_iterator *iter, int flags)
kmemtrace_print_alloc(struct trace_iterator *iter, int flags,
struct trace_event *event)
{
struct trace_seq *s = &iter->seq;
struct kmemtrace_alloc_entry *entry;
Expand All @@ -263,7 +264,8 @@ kmemtrace_print_alloc(struct trace_iterator *iter, int flags)
}

static enum print_line_t
kmemtrace_print_free(struct trace_iterator *iter, int flags)
kmemtrace_print_free(struct trace_iterator *iter, int flags,
struct trace_event *event)
{
struct trace_seq *s = &iter->seq;
struct kmemtrace_free_entry *entry;
Expand All @@ -281,7 +283,8 @@ kmemtrace_print_free(struct trace_iterator *iter, int flags)
}

static enum print_line_t
kmemtrace_print_alloc_user(struct trace_iterator *iter, int flags)
kmemtrace_print_alloc_user(struct trace_iterator *iter, int flags,
struct trace_event *event)
{
struct trace_seq *s = &iter->seq;
struct kmemtrace_alloc_entry *entry;
Expand Down Expand Up @@ -315,7 +318,8 @@ kmemtrace_print_alloc_user(struct trace_iterator *iter, int flags)
}

static enum print_line_t
kmemtrace_print_free_user(struct trace_iterator *iter, int flags)
kmemtrace_print_free_user(struct trace_iterator *iter, int flags,
struct trace_event *event)
{
struct trace_seq *s = &iter->seq;
struct kmemtrace_free_entry *entry;
Expand Down Expand Up @@ -469,18 +473,26 @@ static enum print_line_t kmemtrace_print_line(struct trace_iterator *iter)
}
}

static struct trace_event kmem_trace_alloc = {
.type = TRACE_KMEM_ALLOC,
static struct trace_event_functions kmem_trace_alloc_funcs = {
.trace = kmemtrace_print_alloc,
.binary = kmemtrace_print_alloc_user,
};

static struct trace_event kmem_trace_free = {
.type = TRACE_KMEM_FREE,
static struct trace_event kmem_trace_alloc = {
.type = TRACE_KMEM_ALLOC,
.funcs = &kmem_trace_alloc_funcs,
};

static struct trace_event_functions kmem_trace_free_funcs = {
.trace = kmemtrace_print_free,
.binary = kmemtrace_print_free_user,
};

static struct trace_event kmem_trace_free = {
.type = TRACE_KMEM_FREE,
.funcs = &kmem_trace_free_funcs,
};

static struct tracer kmem_tracer __read_mostly = {
.name = "kmemtrace",
.init = kmem_trace_init,
Expand Down
9 changes: 5 additions & 4 deletions kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1936,7 +1936,7 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
}

if (event)
return event->trace(iter, sym_flags);
return event->funcs->trace(iter, sym_flags, event);

if (!trace_seq_printf(s, "Unknown type %d\n", entry->type))
goto partial;
Expand All @@ -1962,7 +1962,7 @@ static enum print_line_t print_raw_fmt(struct trace_iterator *iter)

event = ftrace_find_event(entry->type);
if (event)
return event->raw(iter, 0);
return event->funcs->raw(iter, 0, event);

if (!trace_seq_printf(s, "%d ?\n", entry->type))
goto partial;
Expand All @@ -1989,7 +1989,7 @@ static enum print_line_t print_hex_fmt(struct trace_iterator *iter)

event = ftrace_find_event(entry->type);
if (event) {
enum print_line_t ret = event->hex(iter, 0);
enum print_line_t ret = event->funcs->hex(iter, 0, event);
if (ret != TRACE_TYPE_HANDLED)
return ret;
}
Expand All @@ -2014,7 +2014,8 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
}

event = ftrace_find_event(entry->type);
return event ? event->binary(iter, 0) : TRACE_TYPE_HANDLED;
return event ? event->funcs->binary(iter, 0, event) :
TRACE_TYPE_HANDLED;
}

int trace_empty(struct trace_iterator *iter)
Expand Down
8 changes: 6 additions & 2 deletions kernel/trace/trace_branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ static void branch_trace_reset(struct trace_array *tr)
}

static enum print_line_t trace_branch_print(struct trace_iterator *iter,
int flags)
int flags, struct trace_event *event)
{
struct trace_branch *field;

Expand All @@ -167,9 +167,13 @@ static void branch_print_header(struct seq_file *s)
" |\n");
}

static struct trace_event_functions trace_branch_funcs = {
.trace = trace_branch_print,
};

static struct trace_event trace_branch_event = {
.type = TRACE_BRANCH,
.trace = trace_branch_print,
.funcs = &trace_branch_funcs,
};

static struct tracer branch_trace __read_mostly =
Expand Down
13 changes: 9 additions & 4 deletions kernel/trace/trace_functions_graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
if (!event)
return TRACE_TYPE_UNHANDLED;

ret = event->trace(iter, sym_flags);
ret = event->funcs->trace(iter, sym_flags, event);
if (ret != TRACE_TYPE_HANDLED)
return ret;
}
Expand Down Expand Up @@ -1112,7 +1112,8 @@ print_graph_function(struct trace_iterator *iter)
}

static enum print_line_t
print_graph_function_event(struct trace_iterator *iter, int flags)
print_graph_function_event(struct trace_iterator *iter, int flags,
struct trace_event *event)
{
return print_graph_function(iter);
}
Expand Down Expand Up @@ -1225,14 +1226,18 @@ void graph_trace_close(struct trace_iterator *iter)
}
}

static struct trace_event_functions graph_functions = {
.trace = print_graph_function_event,
};

static struct trace_event graph_trace_entry_event = {
.type = TRACE_GRAPH_ENT,
.trace = print_graph_function_event,
.funcs = &graph_functions,
};

static struct trace_event graph_trace_ret_event = {
.type = TRACE_GRAPH_RET,
.trace = print_graph_function_event,
.funcs = &graph_functions
};

static struct tracer graph_trace __read_mostly = {
Expand Down
22 changes: 14 additions & 8 deletions kernel/trace/trace_kprobe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1011,16 +1011,15 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,

/* Event entry printers */
enum print_line_t
print_kprobe_event(struct trace_iterator *iter, int flags)
print_kprobe_event(struct trace_iterator *iter, int flags,
struct trace_event *event)
{
struct kprobe_trace_entry *field;
struct trace_seq *s = &iter->seq;
struct trace_event *event;
struct trace_probe *tp;
int i;

field = (struct kprobe_trace_entry *)iter->ent;
event = ftrace_find_event(field->ent.type);
tp = container_of(event, struct trace_probe, event);

if (!trace_seq_printf(s, "%s: (", tp->call.name))
Expand All @@ -1046,16 +1045,15 @@ print_kprobe_event(struct trace_iterator *iter, int flags)
}

enum print_line_t
print_kretprobe_event(struct trace_iterator *iter, int flags)
print_kretprobe_event(struct trace_iterator *iter, int flags,
struct trace_event *event)
{
struct kretprobe_trace_entry *field;
struct trace_seq *s = &iter->seq;
struct trace_event *event;
struct trace_probe *tp;
int i;

field = (struct kretprobe_trace_entry *)iter->ent;
event = ftrace_find_event(field->ent.type);
tp = container_of(event, struct trace_probe, event);

if (!trace_seq_printf(s, "%s: (", tp->call.name))
Expand Down Expand Up @@ -1351,20 +1349,28 @@ int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
return 0; /* We don't tweek kernel, so just return 0 */
}

static struct trace_event_functions kretprobe_funcs = {
.trace = print_kretprobe_event
};

static struct trace_event_functions kprobe_funcs = {
.trace = print_kprobe_event
};

static int register_probe_event(struct trace_probe *tp)
{
struct ftrace_event_call *call = &tp->call;
int ret;

/* Initialize ftrace_event_call */
if (probe_is_return(tp)) {
tp->event.trace = print_kretprobe_event;
tp->event.funcs = &kretprobe_funcs;
INIT_LIST_HEAD(&call->class->fields);
call->class->raw_init = probe_event_raw_init;
call->class->define_fields = kretprobe_event_define_fields;
} else {
INIT_LIST_HEAD(&call->class->fields);
tp->event.trace = print_kprobe_event;
tp->event.funcs = &kprobe_funcs;
call->class->raw_init = probe_event_raw_init;
call->class->define_fields = kprobe_event_define_fields;
}
Expand Down
Loading

0 comments on commit a9a5776

Please sign in to comment.