aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-04-22 10:35:55 -0400
committerSteven Rostedt <rostedt@goodmis.org>2010-05-14 14:20:23 -0400
commit2e33af029556cb8bd22bf4f86f42d540249177ea (patch)
tree8a479d21300c7692d61093846054f626e3e71ed5
parent2239291aeb0379fe47980b0e560e0eb9fd7e82ec (diff)
tracing: Move fields from event to class structure
Move the defined fields from the event to the class structure. Since the fields of the event are defined by the class they belong to, it makes sense to have the class hold the information instead of the individual events. The events of the same class would just hold duplicate information. After this change the size of the kernel dropped another 3K: text data bss dec hex filename 4913961 1088356 861512 6863829 68bbd5 vmlinux.orig 4900252 1057412 861512 6819176 680d68 vmlinux.regs 4900375 1053380 861512 6815267 67fe23 vmlinux.fields Although the text increased, this was mainly due to the C files having to adapt to the change. This is a constant increase, where new tracepoints will not increase the Text. But the big drop is in the data size (as well as needed allocations to hold the fields). This will give even more savings as more tracepoints are created. Note, if just TRACE_EVENT()s are used and not DECLARE_EVENT_CLASS() with several DEFINE_EVENT()s, then the savings will be lost. But we are pushing developers to consolidate events with DEFINE_EVENT() so this should not be an issue. The kprobes define a unique class to every new event, but are dynamic so it should not be a issue. The syscalls however have a single class but the fields for the individual events are different. The syscalls use a metadata to define the fields. I moved the fields list from the event to the metadata and added a "get_fields()" function to the class. This function is used to find the fields. For normal events and kprobes, get_fields() just returns a pointer to the fields list_head in the class. For syscall events, it returns the fields list_head in the metadata for the event. v2: Fixed the syscall fields. The syscall metadata needs a list of fields for both enter and exit. Acked-by: Frederic Weisbecker <fweisbec@gmail.com> Acked-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Acked-by: Masami Hiramatsu <mhiramat@redhat.com> Cc: Tom Zanussi <tzanussi@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--include/linux/ftrace_event.h5
-rw-r--r--include/linux/syscalls.h14
-rw-r--r--include/trace/ftrace.h11
-rw-r--r--include/trace/syscall.h4
-rw-r--r--kernel/trace/trace.h3
-rw-r--r--kernel/trace/trace_events.c48
-rw-r--r--kernel/trace/trace_events_filter.c10
-rw-r--r--kernel/trace/trace_export.c14
-rw-r--r--kernel/trace/trace_kprobe.c8
-rw-r--r--kernel/trace/trace_syscalls.c31
10 files changed, 102 insertions, 46 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index e665ed38b4bf..479c3c1876e6 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -130,6 +130,9 @@ struct ftrace_event_class {
130#endif 130#endif
131 int (*reg)(struct ftrace_event_call *event, 131 int (*reg)(struct ftrace_event_call *event,
132 enum trace_reg type); 132 enum trace_reg type);
133 int (*define_fields)(struct ftrace_event_call *);
134 struct list_head *(*get_fields)(struct ftrace_event_call *);
135 struct list_head fields;
133}; 136};
134 137
135struct ftrace_event_call { 138struct ftrace_event_call {
@@ -142,8 +145,6 @@ struct ftrace_event_call {
142 int id; 145 int id;
143 const char *print_fmt; 146 const char *print_fmt;
144 int (*raw_init)(struct ftrace_event_call *); 147 int (*raw_init)(struct ftrace_event_call *);
145 int (*define_fields)(struct ftrace_event_call *);
146 struct list_head fields;
147 int filter_active; 148 int filter_active;
148 struct event_filter *filter; 149 struct event_filter *filter;
149 void *mod; 150 void *mod;
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index e3348c4c22e8..fd0f1f248cd8 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -122,7 +122,7 @@ extern struct ftrace_event_class event_class_syscall_enter;
122extern struct ftrace_event_class event_class_syscall_exit; 122extern struct ftrace_event_class event_class_syscall_exit;
123 123
124#define SYSCALL_TRACE_ENTER_EVENT(sname) \ 124#define SYSCALL_TRACE_ENTER_EVENT(sname) \
125 static const struct syscall_metadata __syscall_meta_##sname; \ 125 static struct syscall_metadata __syscall_meta_##sname; \
126 static struct ftrace_event_call \ 126 static struct ftrace_event_call \
127 __attribute__((__aligned__(4))) event_enter_##sname; \ 127 __attribute__((__aligned__(4))) event_enter_##sname; \
128 static struct trace_event enter_syscall_print_##sname = { \ 128 static struct trace_event enter_syscall_print_##sname = { \
@@ -136,12 +136,11 @@ extern struct ftrace_event_class event_class_syscall_exit;
136 .class = &event_class_syscall_enter, \ 136 .class = &event_class_syscall_enter, \
137 .event = &enter_syscall_print_##sname, \ 137 .event = &enter_syscall_print_##sname, \
138 .raw_init = init_syscall_trace, \ 138 .raw_init = init_syscall_trace, \
139 .define_fields = syscall_enter_define_fields, \
140 .data = (void *)&__syscall_meta_##sname,\ 139 .data = (void *)&__syscall_meta_##sname,\
141 } 140 }
142 141
143#define SYSCALL_TRACE_EXIT_EVENT(sname) \ 142#define SYSCALL_TRACE_EXIT_EVENT(sname) \
144 static const struct syscall_metadata __syscall_meta_##sname; \ 143 static struct syscall_metadata __syscall_meta_##sname; \
145 static struct ftrace_event_call \ 144 static struct ftrace_event_call \
146 __attribute__((__aligned__(4))) event_exit_##sname; \ 145 __attribute__((__aligned__(4))) event_exit_##sname; \
147 static struct trace_event exit_syscall_print_##sname = { \ 146 static struct trace_event exit_syscall_print_##sname = { \
@@ -155,14 +154,13 @@ extern struct ftrace_event_class event_class_syscall_exit;
155 .class = &event_class_syscall_exit, \ 154 .class = &event_class_syscall_exit, \
156 .event = &exit_syscall_print_##sname, \ 155 .event = &exit_syscall_print_##sname, \
157 .raw_init = init_syscall_trace, \ 156 .raw_init = init_syscall_trace, \
158 .define_fields = syscall_exit_define_fields, \
159 .data = (void *)&__syscall_meta_##sname,\ 157 .data = (void *)&__syscall_meta_##sname,\
160 } 158 }
161 159
162#define SYSCALL_METADATA(sname, nb) \ 160#define SYSCALL_METADATA(sname, nb) \
163 SYSCALL_TRACE_ENTER_EVENT(sname); \ 161 SYSCALL_TRACE_ENTER_EVENT(sname); \
164 SYSCALL_TRACE_EXIT_EVENT(sname); \ 162 SYSCALL_TRACE_EXIT_EVENT(sname); \
165 static const struct syscall_metadata __used \ 163 static struct syscall_metadata __used \
166 __attribute__((__aligned__(4))) \ 164 __attribute__((__aligned__(4))) \
167 __attribute__((section("__syscalls_metadata"))) \ 165 __attribute__((section("__syscalls_metadata"))) \
168 __syscall_meta_##sname = { \ 166 __syscall_meta_##sname = { \
@@ -172,12 +170,14 @@ extern struct ftrace_event_class event_class_syscall_exit;
172 .args = args_##sname, \ 170 .args = args_##sname, \
173 .enter_event = &event_enter_##sname, \ 171 .enter_event = &event_enter_##sname, \
174 .exit_event = &event_exit_##sname, \ 172 .exit_event = &event_exit_##sname, \
173 .enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \
174 .exit_fields = LIST_HEAD_INIT(__syscall_meta_##sname.exit_fields), \
175 }; 175 };
176 176
177#define SYSCALL_DEFINE0(sname) \ 177#define SYSCALL_DEFINE0(sname) \
178 SYSCALL_TRACE_ENTER_EVENT(_##sname); \ 178 SYSCALL_TRACE_ENTER_EVENT(_##sname); \
179 SYSCALL_TRACE_EXIT_EVENT(_##sname); \ 179 SYSCALL_TRACE_EXIT_EVENT(_##sname); \
180 static const struct syscall_metadata __used \ 180 static struct syscall_metadata __used \
181 __attribute__((__aligned__(4))) \ 181 __attribute__((__aligned__(4))) \
182 __attribute__((section("__syscalls_metadata"))) \ 182 __attribute__((section("__syscalls_metadata"))) \
183 __syscall_meta__##sname = { \ 183 __syscall_meta__##sname = { \
@@ -185,6 +185,8 @@ extern struct ftrace_event_class event_class_syscall_exit;
185 .nb_args = 0, \ 185 .nb_args = 0, \
186 .enter_event = &event_enter__##sname, \ 186 .enter_event = &event_enter__##sname, \
187 .exit_event = &event_exit__##sname, \ 187 .exit_event = &event_exit__##sname, \
188 .enter_fields = LIST_HEAD_INIT(__syscall_meta__##sname.enter_fields), \
189 .exit_fields = LIST_HEAD_INIT(__syscall_meta__##sname.exit_fields), \
188 }; \ 190 }; \
189 asmlinkage long sys_##sname(void) 191 asmlinkage long sys_##sname(void)
190#else 192#else
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 26d132418f92..c7e3bcd5d52f 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -430,6 +430,9 @@ static inline notrace int ftrace_get_offsets_##call( \
430 * 430 *
431 * static struct ftrace_event_class __used event_class_<template> = { 431 * static struct ftrace_event_class __used event_class_<template> = {
432 * .system = "<system>", 432 * .system = "<system>",
433 * .define_fields = ftrace_define_fields_<call>,
434 * .fields = LIST_HEAD_INIT(event_class_##call.fields), \
435 * .probe = ftrace_raw_event_##call, \
433 * }; 436 * };
434 * 437 *
435 * static struct ftrace_event_call __used 438 * static struct ftrace_event_call __used
@@ -438,10 +441,8 @@ static inline notrace int ftrace_get_offsets_##call( \
438 * .name = "<call>", 441 * .name = "<call>",
439 * .class = event_class_<template>, 442 * .class = event_class_<template>,
440 * .raw_init = trace_event_raw_init, 443 * .raw_init = trace_event_raw_init,
441 * .regfunc = ftrace_raw_reg_event_<call>, 444 * .event = &ftrace_event_type_<call>,
442 * .unregfunc = ftrace_raw_unreg_event_<call>,
443 * .print_fmt = print_fmt_<call>, 445 * .print_fmt = print_fmt_<call>,
444 * .define_fields = ftrace_define_fields_<call>,
445 * }; 446 * };
446 * 447 *
447 */ 448 */
@@ -563,6 +564,8 @@ _TRACE_PERF_PROTO(call, PARAMS(proto)); \
563static const char print_fmt_##call[] = print; \ 564static const char print_fmt_##call[] = print; \
564static struct ftrace_event_class __used event_class_##call = { \ 565static struct ftrace_event_class __used event_class_##call = { \
565 .system = __stringify(TRACE_SYSTEM), \ 566 .system = __stringify(TRACE_SYSTEM), \
567 .define_fields = ftrace_define_fields_##call, \
568 .fields = LIST_HEAD_INIT(event_class_##call.fields),\
566 .probe = ftrace_raw_event_##call, \ 569 .probe = ftrace_raw_event_##call, \
567 _TRACE_PERF_INIT(call) \ 570 _TRACE_PERF_INIT(call) \
568}; 571};
@@ -578,7 +581,6 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
578 .event = &ftrace_event_type_##call, \ 581 .event = &ftrace_event_type_##call, \
579 .raw_init = trace_event_raw_init, \ 582 .raw_init = trace_event_raw_init, \
580 .print_fmt = print_fmt_##template, \ 583 .print_fmt = print_fmt_##template, \
581 .define_fields = ftrace_define_fields_##template, \
582}; 584};
583 585
584#undef DEFINE_EVENT_PRINT 586#undef DEFINE_EVENT_PRINT
@@ -594,7 +596,6 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
594 .event = &ftrace_event_type_##call, \ 596 .event = &ftrace_event_type_##call, \
595 .raw_init = trace_event_raw_init, \ 597 .raw_init = trace_event_raw_init, \
596 .print_fmt = print_fmt_##call, \ 598 .print_fmt = print_fmt_##call, \
597 .define_fields = ftrace_define_fields_##template, \
598} 599}
599 600
600#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 601#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
diff --git a/include/trace/syscall.h b/include/trace/syscall.h
index e5e5f48dbfb3..39647743cd95 100644
--- a/include/trace/syscall.h
+++ b/include/trace/syscall.h
@@ -25,6 +25,8 @@ struct syscall_metadata {
25 int nb_args; 25 int nb_args;
26 const char **types; 26 const char **types;
27 const char **args; 27 const char **args;
28 struct list_head enter_fields;
29 struct list_head exit_fields;
28 30
29 struct ftrace_event_call *enter_event; 31 struct ftrace_event_call *enter_event;
30 struct ftrace_event_call *exit_event; 32 struct ftrace_event_call *exit_event;
@@ -34,8 +36,6 @@ struct syscall_metadata {
34extern unsigned long arch_syscall_addr(int nr); 36extern unsigned long arch_syscall_addr(int nr);
35extern int init_syscall_trace(struct ftrace_event_call *call); 37extern int init_syscall_trace(struct ftrace_event_call *call);
36 38
37extern int syscall_enter_define_fields(struct ftrace_event_call *call);
38extern int syscall_exit_define_fields(struct ftrace_event_call *call);
39extern int reg_event_syscall_enter(struct ftrace_event_call *call); 39extern int reg_event_syscall_enter(struct ftrace_event_call *call);
40extern void unreg_event_syscall_enter(struct ftrace_event_call *call); 40extern void unreg_event_syscall_enter(struct ftrace_event_call *call);
41extern int reg_event_syscall_exit(struct ftrace_event_call *call); 41extern int reg_event_syscall_exit(struct ftrace_event_call *call);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 911e9864e94a..c88c563a59a5 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -794,6 +794,9 @@ extern void print_subsystem_event_filter(struct event_subsystem *system,
794 struct trace_seq *s); 794 struct trace_seq *s);
795extern int filter_assign_type(const char *type); 795extern int filter_assign_type(const char *type);
796 796
797struct list_head *
798trace_get_fields(struct ftrace_event_call *event_call);
799
797static inline int 800static inline int
798filter_check_discard(struct ftrace_event_call *call, void *rec, 801filter_check_discard(struct ftrace_event_call *call, void *rec,
799 struct ring_buffer *buffer, 802 struct ring_buffer *buffer,
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 19d1eb0a7188..acc0f55742c3 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -29,11 +29,23 @@ DEFINE_MUTEX(event_mutex);
29 29
30LIST_HEAD(ftrace_events); 30LIST_HEAD(ftrace_events);
31 31
32struct list_head *
33trace_get_fields(struct ftrace_event_call *event_call)
34{
35 if (!event_call->class->get_fields)
36 return &event_call->class->fields;
37 return event_call->class->get_fields(event_call);
38}
39
32int trace_define_field(struct ftrace_event_call *call, const char *type, 40int trace_define_field(struct ftrace_event_call *call, const char *type,
33 const char *name, int offset, int size, int is_signed, 41 const char *name, int offset, int size, int is_signed,
34 int filter_type) 42 int filter_type)
35{ 43{
36 struct ftrace_event_field *field; 44 struct ftrace_event_field *field;
45 struct list_head *head;
46
47 if (WARN_ON(!call->class))
48 return 0;
37 49
38 field = kzalloc(sizeof(*field), GFP_KERNEL); 50 field = kzalloc(sizeof(*field), GFP_KERNEL);
39 if (!field) 51 if (!field)
@@ -56,7 +68,8 @@ int trace_define_field(struct ftrace_event_call *call, const char *type,
56 field->size = size; 68 field->size = size;
57 field->is_signed = is_signed; 69 field->is_signed = is_signed;
58 70
59 list_add(&field->link, &call->fields); 71 head = trace_get_fields(call);
72 list_add(&field->link, head);
60 73
61 return 0; 74 return 0;
62 75
@@ -94,8 +107,10 @@ static int trace_define_common_fields(struct ftrace_event_call *call)
94void trace_destroy_fields(struct ftrace_event_call *call) 107void trace_destroy_fields(struct ftrace_event_call *call)
95{ 108{
96 struct ftrace_event_field *field, *next; 109 struct ftrace_event_field *field, *next;
110 struct list_head *head;
97 111
98 list_for_each_entry_safe(field, next, &call->fields, link) { 112 head = trace_get_fields(call);
113 list_for_each_entry_safe(field, next, head, link) {
99 list_del(&field->link); 114 list_del(&field->link);
100 kfree(field->type); 115 kfree(field->type);
101 kfree(field->name); 116 kfree(field->name);
@@ -111,7 +126,6 @@ int trace_event_raw_init(struct ftrace_event_call *call)
111 if (!id) 126 if (!id)
112 return -ENODEV; 127 return -ENODEV;
113 call->id = id; 128 call->id = id;
114 INIT_LIST_HEAD(&call->fields);
115 129
116 return 0; 130 return 0;
117} 131}
@@ -537,6 +551,7 @@ event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
537{ 551{
538 struct ftrace_event_call *call = filp->private_data; 552 struct ftrace_event_call *call = filp->private_data;
539 struct ftrace_event_field *field; 553 struct ftrace_event_field *field;
554 struct list_head *head;
540 struct trace_seq *s; 555 struct trace_seq *s;
541 int common_field_count = 5; 556 int common_field_count = 5;
542 char *buf; 557 char *buf;
@@ -555,7 +570,8 @@ event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
555 trace_seq_printf(s, "ID: %d\n", call->id); 570 trace_seq_printf(s, "ID: %d\n", call->id);
556 trace_seq_printf(s, "format:\n"); 571 trace_seq_printf(s, "format:\n");
557 572
558 list_for_each_entry_reverse(field, &call->fields, link) { 573 head = trace_get_fields(call);
574 list_for_each_entry_reverse(field, head, link) {
559 /* 575 /*
560 * Smartly shows the array type(except dynamic array). 576 * Smartly shows the array type(except dynamic array).
561 * Normal: 577 * Normal:
@@ -931,6 +947,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
931 const struct file_operations *filter, 947 const struct file_operations *filter,
932 const struct file_operations *format) 948 const struct file_operations *format)
933{ 949{
950 struct list_head *head;
934 int ret; 951 int ret;
935 952
936 /* 953 /*
@@ -957,14 +974,21 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
957 id); 974 id);
958#endif 975#endif
959 976
960 if (call->define_fields) { 977 if (call->class->define_fields) {
961 ret = trace_define_common_fields(call); 978 /*
962 if (!ret) 979 * Other events may have the same class. Only update
963 ret = call->define_fields(call); 980 * the fields if they are not already defined.
964 if (ret < 0) { 981 */
965 pr_warning("Could not initialize trace point" 982 head = trace_get_fields(call);
966 " events/%s\n", call->name); 983 if (list_empty(head)) {
967 return ret; 984 ret = trace_define_common_fields(call);
985 if (!ret)
986 ret = call->class->define_fields(call);
987 if (ret < 0) {
988 pr_warning("Could not initialize trace point"
989 " events/%s\n", call->name);
990 return ret;
991 }
968 } 992 }
969 trace_create_file("filter", 0644, call->dir, call, 993 trace_create_file("filter", 0644, call->dir, call,
970 filter); 994 filter);
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index ca329603d0bf..961f99b74bdd 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -500,8 +500,10 @@ static struct ftrace_event_field *
500find_event_field(struct ftrace_event_call *call, char *name) 500find_event_field(struct ftrace_event_call *call, char *name)
501{ 501{
502 struct ftrace_event_field *field; 502 struct ftrace_event_field *field;
503 struct list_head *head;
503 504
504 list_for_each_entry(field, &call->fields, link) { 505 head = trace_get_fields(call);
506 list_for_each_entry(field, head, link) {
505 if (!strcmp(field->name, name)) 507 if (!strcmp(field->name, name))
506 return field; 508 return field;
507 } 509 }
@@ -625,7 +627,7 @@ static int init_subsystem_preds(struct event_subsystem *system)
625 int err; 627 int err;
626 628
627 list_for_each_entry(call, &ftrace_events, list) { 629 list_for_each_entry(call, &ftrace_events, list) {
628 if (!call->define_fields) 630 if (!call->class || !call->class->define_fields)
629 continue; 631 continue;
630 632
631 if (strcmp(call->class->system, system->name) != 0) 633 if (strcmp(call->class->system, system->name) != 0)
@@ -644,7 +646,7 @@ static void filter_free_subsystem_preds(struct event_subsystem *system)
644 struct ftrace_event_call *call; 646 struct ftrace_event_call *call;
645 647
646 list_for_each_entry(call, &ftrace_events, list) { 648 list_for_each_entry(call, &ftrace_events, list) {
647 if (!call->define_fields) 649 if (!call->class || !call->class->define_fields)
648 continue; 650 continue;
649 651
650 if (strcmp(call->class->system, system->name) != 0) 652 if (strcmp(call->class->system, system->name) != 0)
@@ -1249,7 +1251,7 @@ static int replace_system_preds(struct event_subsystem *system,
1249 list_for_each_entry(call, &ftrace_events, list) { 1251 list_for_each_entry(call, &ftrace_events, list) {
1250 struct event_filter *filter = call->filter; 1252 struct event_filter *filter = call->filter;
1251 1253
1252 if (!call->define_fields) 1254 if (!call->class || !call->class->define_fields)
1253 continue; 1255 continue;
1254 1256
1255 if (strcmp(call->class->system, system->name) != 0) 1257 if (strcmp(call->class->system, system->name) != 0)
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
index 7f16e2163817..e700a0c1803f 100644
--- a/kernel/trace/trace_export.c
+++ b/kernel/trace/trace_export.c
@@ -18,10 +18,6 @@
18#undef TRACE_SYSTEM 18#undef TRACE_SYSTEM
19#define TRACE_SYSTEM ftrace 19#define TRACE_SYSTEM ftrace
20 20
21struct ftrace_event_class event_class_ftrace = {
22 .system = __stringify(TRACE_SYSTEM),
23};
24
25/* not needed for this file */ 21/* not needed for this file */
26#undef __field_struct 22#undef __field_struct
27#define __field_struct(type, item) 23#define __field_struct(type, item)
@@ -131,7 +127,7 @@ ftrace_define_fields_##name(struct ftrace_event_call *event_call) \
131 127
132static int ftrace_raw_init_event(struct ftrace_event_call *call) 128static int ftrace_raw_init_event(struct ftrace_event_call *call)
133{ 129{
134 INIT_LIST_HEAD(&call->fields); 130 INIT_LIST_HEAD(&call->class->fields);
135 return 0; 131 return 0;
136} 132}
137 133
@@ -159,15 +155,19 @@ static int ftrace_raw_init_event(struct ftrace_event_call *call)
159#undef FTRACE_ENTRY 155#undef FTRACE_ENTRY
160#define FTRACE_ENTRY(call, struct_name, type, tstruct, print) \ 156#define FTRACE_ENTRY(call, struct_name, type, tstruct, print) \
161 \ 157 \
158struct ftrace_event_class event_class_ftrace_##call = { \
159 .system = __stringify(TRACE_SYSTEM), \
160 .define_fields = ftrace_define_fields_##call, \
161}; \
162 \
162struct ftrace_event_call __used \ 163struct ftrace_event_call __used \
163__attribute__((__aligned__(4))) \ 164__attribute__((__aligned__(4))) \
164__attribute__((section("_ftrace_events"))) event_##call = { \ 165__attribute__((section("_ftrace_events"))) event_##call = { \
165 .name = #call, \ 166 .name = #call, \
166 .id = type, \ 167 .id = type, \
167 .class = &event_class_ftrace, \ 168 .class = &event_class_ftrace_##call, \
168 .raw_init = ftrace_raw_init_event, \ 169 .raw_init = ftrace_raw_init_event, \
169 .print_fmt = print, \ 170 .print_fmt = print, \
170 .define_fields = ftrace_define_fields_##call, \
171}; \ 171}; \
172 172
173#include "trace_entries.h" 173#include "trace_entries.h"
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index f8af21a53f0c..b14bf745356f 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -1112,8 +1112,6 @@ static void probe_event_disable(struct ftrace_event_call *call)
1112 1112
1113static int probe_event_raw_init(struct ftrace_event_call *event_call) 1113static int probe_event_raw_init(struct ftrace_event_call *event_call)
1114{ 1114{
1115 INIT_LIST_HEAD(&event_call->fields);
1116
1117 return 0; 1115 return 0;
1118} 1116}
1119 1117
@@ -1362,11 +1360,13 @@ static int register_probe_event(struct trace_probe *tp)
1362 if (probe_is_return(tp)) { 1360 if (probe_is_return(tp)) {
1363 tp->event.trace = print_kretprobe_event; 1361 tp->event.trace = print_kretprobe_event;
1364 call->raw_init = probe_event_raw_init; 1362 call->raw_init = probe_event_raw_init;
1365 call->define_fields = kretprobe_event_define_fields; 1363 INIT_LIST_HEAD(&call->class->fields);
1364 call->class->define_fields = kretprobe_event_define_fields;
1366 } else { 1365 } else {
1367 tp->event.trace = print_kprobe_event; 1366 tp->event.trace = print_kprobe_event;
1368 call->raw_init = probe_event_raw_init; 1367 call->raw_init = probe_event_raw_init;
1369 call->define_fields = kprobe_event_define_fields; 1368 INIT_LIST_HEAD(&call->class->fields);
1369 call->class->define_fields = kprobe_event_define_fields;
1370 } 1370 }
1371 if (set_print_fmt(tp) < 0) 1371 if (set_print_fmt(tp) < 0)
1372 return -ENOMEM; 1372 return -ENOMEM;
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index a21d366cae46..cceccf0d2e91 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -20,14 +20,37 @@ static int syscall_enter_register(struct ftrace_event_call *event,
20static int syscall_exit_register(struct ftrace_event_call *event, 20static int syscall_exit_register(struct ftrace_event_call *event,
21 enum trace_reg type); 21 enum trace_reg type);
22 22
23static int syscall_enter_define_fields(struct ftrace_event_call *call);
24static int syscall_exit_define_fields(struct ftrace_event_call *call);
25
26static struct list_head *
27syscall_get_enter_fields(struct ftrace_event_call *call)
28{
29 struct syscall_metadata *entry = call->data;
30
31 return &entry->enter_fields;
32}
33
34static struct list_head *
35syscall_get_exit_fields(struct ftrace_event_call *call)
36{
37 struct syscall_metadata *entry = call->data;
38
39 return &entry->exit_fields;
40}
41
23struct ftrace_event_class event_class_syscall_enter = { 42struct ftrace_event_class event_class_syscall_enter = {
24 .system = "syscalls", 43 .system = "syscalls",
25 .reg = syscall_enter_register 44 .reg = syscall_enter_register,
45 .define_fields = syscall_enter_define_fields,
46 .get_fields = syscall_get_enter_fields,
26}; 47};
27 48
28struct ftrace_event_class event_class_syscall_exit = { 49struct ftrace_event_class event_class_syscall_exit = {
29 .system = "syscalls", 50 .system = "syscalls",
30 .reg = syscall_exit_register 51 .reg = syscall_exit_register,
52 .define_fields = syscall_exit_define_fields,
53 .get_fields = syscall_get_exit_fields,
31}; 54};
32 55
33extern unsigned long __start_syscalls_metadata[]; 56extern unsigned long __start_syscalls_metadata[];
@@ -220,7 +243,7 @@ static void free_syscall_print_fmt(struct ftrace_event_call *call)
220 kfree(call->print_fmt); 243 kfree(call->print_fmt);
221} 244}
222 245
223int syscall_enter_define_fields(struct ftrace_event_call *call) 246static int syscall_enter_define_fields(struct ftrace_event_call *call)
224{ 247{
225 struct syscall_trace_enter trace; 248 struct syscall_trace_enter trace;
226 struct syscall_metadata *meta = call->data; 249 struct syscall_metadata *meta = call->data;
@@ -243,7 +266,7 @@ int syscall_enter_define_fields(struct ftrace_event_call *call)
243 return ret; 266 return ret;
244} 267}
245 268
246int syscall_exit_define_fields(struct ftrace_event_call *call) 269static int syscall_exit_define_fields(struct ftrace_event_call *call)
247{ 270{
248 struct syscall_trace_exit trace; 271 struct syscall_trace_exit trace;
249 int ret; 272 int ret;