aboutsummaryrefslogtreecommitdiffstats
path: root/include
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 /include
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>
Diffstat (limited to 'include')
-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
4 files changed, 19 insertions, 15 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);