diff options
-rw-r--r-- | include/linux/ftrace_event.h | 5 | ||||
-rw-r--r-- | include/linux/syscalls.h | 14 | ||||
-rw-r--r-- | include/trace/ftrace.h | 11 | ||||
-rw-r--r-- | include/trace/syscall.h | 4 | ||||
-rw-r--r-- | kernel/trace/trace.h | 3 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 48 | ||||
-rw-r--r-- | kernel/trace/trace_events_filter.c | 10 | ||||
-rw-r--r-- | kernel/trace/trace_export.c | 14 | ||||
-rw-r--r-- | kernel/trace/trace_kprobe.c | 8 | ||||
-rw-r--r-- | kernel/trace/trace_syscalls.c | 31 |
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 | ||
135 | struct ftrace_event_call { | 138 | struct 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; | |||
122 | extern struct ftrace_event_class event_class_syscall_exit; | 122 | extern 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)); \ | |||
563 | static const char print_fmt_##call[] = print; \ | 564 | static const char print_fmt_##call[] = print; \ |
564 | static struct ftrace_event_class __used event_class_##call = { \ | 565 | static 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 { | |||
34 | extern unsigned long arch_syscall_addr(int nr); | 36 | extern unsigned long arch_syscall_addr(int nr); |
35 | extern int init_syscall_trace(struct ftrace_event_call *call); | 37 | extern int init_syscall_trace(struct ftrace_event_call *call); |
36 | 38 | ||
37 | extern int syscall_enter_define_fields(struct ftrace_event_call *call); | ||
38 | extern int syscall_exit_define_fields(struct ftrace_event_call *call); | ||
39 | extern int reg_event_syscall_enter(struct ftrace_event_call *call); | 39 | extern int reg_event_syscall_enter(struct ftrace_event_call *call); |
40 | extern void unreg_event_syscall_enter(struct ftrace_event_call *call); | 40 | extern void unreg_event_syscall_enter(struct ftrace_event_call *call); |
41 | extern int reg_event_syscall_exit(struct ftrace_event_call *call); | 41 | extern 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); |
795 | extern int filter_assign_type(const char *type); | 795 | extern int filter_assign_type(const char *type); |
796 | 796 | ||
797 | struct list_head * | ||
798 | trace_get_fields(struct ftrace_event_call *event_call); | ||
799 | |||
797 | static inline int | 800 | static inline int |
798 | filter_check_discard(struct ftrace_event_call *call, void *rec, | 801 | filter_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 | ||
30 | LIST_HEAD(ftrace_events); | 30 | LIST_HEAD(ftrace_events); |
31 | 31 | ||
32 | struct list_head * | ||
33 | trace_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 | |||
32 | int trace_define_field(struct ftrace_event_call *call, const char *type, | 40 | int 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) | |||
94 | void trace_destroy_fields(struct ftrace_event_call *call) | 107 | void 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 * | |||
500 | find_event_field(struct ftrace_event_call *call, char *name) | 500 | find_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 | ||
21 | struct 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 | ||
132 | static int ftrace_raw_init_event(struct ftrace_event_call *call) | 128 | static 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 | \ |
158 | struct ftrace_event_class event_class_ftrace_##call = { \ | ||
159 | .system = __stringify(TRACE_SYSTEM), \ | ||
160 | .define_fields = ftrace_define_fields_##call, \ | ||
161 | }; \ | ||
162 | \ | ||
162 | struct ftrace_event_call __used \ | 163 | struct 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 | ||
1113 | static int probe_event_raw_init(struct ftrace_event_call *event_call) | 1113 | static 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, | |||
20 | static int syscall_exit_register(struct ftrace_event_call *event, | 20 | static int syscall_exit_register(struct ftrace_event_call *event, |
21 | enum trace_reg type); | 21 | enum trace_reg type); |
22 | 22 | ||
23 | static int syscall_enter_define_fields(struct ftrace_event_call *call); | ||
24 | static int syscall_exit_define_fields(struct ftrace_event_call *call); | ||
25 | |||
26 | static struct list_head * | ||
27 | syscall_get_enter_fields(struct ftrace_event_call *call) | ||
28 | { | ||
29 | struct syscall_metadata *entry = call->data; | ||
30 | |||
31 | return &entry->enter_fields; | ||
32 | } | ||
33 | |||
34 | static struct list_head * | ||
35 | syscall_get_exit_fields(struct ftrace_event_call *call) | ||
36 | { | ||
37 | struct syscall_metadata *entry = call->data; | ||
38 | |||
39 | return &entry->exit_fields; | ||
40 | } | ||
41 | |||
23 | struct ftrace_event_class event_class_syscall_enter = { | 42 | struct 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 | ||
28 | struct ftrace_event_class event_class_syscall_exit = { | 49 | struct 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 | ||
33 | extern unsigned long __start_syscalls_metadata[]; | 56 | extern 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 | ||
223 | int syscall_enter_define_fields(struct ftrace_event_call *call) | 246 | static 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 | ||
246 | int syscall_exit_define_fields(struct ftrace_event_call *call) | 269 | static 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; |