aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLai Jiangshan <laijs@cn.fujitsu.com>2009-12-15 02:39:45 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-01-06 11:58:32 -0500
commit50307a45f8515f6244e3b08e6b19824b9fbfe293 (patch)
tree3561b9824617845910c09a4f7ef5d29ea6159ddf /kernel
parent509e760cd91c831983097ae174cb6c0b8c6c8e6b (diff)
tracing/syscalls: Init print_fmt for syscall events
This is part of a patch set that removes the show_format method in the ftrace event macros. Add the print_fmt initialization to the syscall events. The print_fmt is still not used, but will be in the follow up patches. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> LKML-Reference: <4B273D41.609@cn.fujitsu.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace_syscalls.c68
1 files changed, 67 insertions, 1 deletions
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 75289f372dd2..1352b0a36fac 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -191,6 +191,67 @@ int syscall_enter_format(struct ftrace_event_call *call, struct trace_seq *s)
191 return trace_seq_putc(s, '\n'); 191 return trace_seq_putc(s, '\n');
192} 192}
193 193
194static
195int __set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len)
196{
197 int i;
198 int pos = 0;
199
200 /* When len=0, we just calculate the needed length */
201#define LEN_OR_ZERO (len ? len - pos : 0)
202
203 pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
204 for (i = 0; i < entry->nb_args; i++) {
205 pos += snprintf(buf + pos, LEN_OR_ZERO, "%s: 0x%%0%zulx%s",
206 entry->args[i], sizeof(unsigned long),
207 i == entry->nb_args - 1 ? "" : ", ");
208 }
209 pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
210
211 for (i = 0; i < entry->nb_args; i++) {
212 pos += snprintf(buf + pos, LEN_OR_ZERO,
213 ", ((unsigned long)(REC->%s))", entry->args[i]);
214 }
215
216#undef LEN_OR_ZERO
217
218 /* return the length of print_fmt */
219 return pos;
220}
221
222static int set_syscall_print_fmt(struct ftrace_event_call *call)
223{
224 char *print_fmt;
225 int len;
226 struct syscall_metadata *entry = call->data;
227
228 if (entry->enter_event != call) {
229 call->print_fmt = "\"0x%lx\", REC->ret";
230 return 0;
231 }
232
233 /* First: called with 0 length to calculate the needed length */
234 len = __set_enter_print_fmt(entry, NULL, 0);
235
236 print_fmt = kmalloc(len + 1, GFP_KERNEL);
237 if (!print_fmt)
238 return -ENOMEM;
239
240 /* Second: actually write the @print_fmt */
241 __set_enter_print_fmt(entry, print_fmt, len + 1);
242 call->print_fmt = print_fmt;
243
244 return 0;
245}
246
247static void free_syscall_print_fmt(struct ftrace_event_call *call)
248{
249 struct syscall_metadata *entry = call->data;
250
251 if (entry->enter_event == call)
252 kfree(call->print_fmt);
253}
254
194int syscall_exit_format(struct ftrace_event_call *call, struct trace_seq *s) 255int syscall_exit_format(struct ftrace_event_call *call, struct trace_seq *s)
195{ 256{
196 int ret; 257 int ret;
@@ -386,9 +447,14 @@ int init_syscall_trace(struct ftrace_event_call *call)
386{ 447{
387 int id; 448 int id;
388 449
450 if (set_syscall_print_fmt(call) < 0)
451 return -ENOMEM;
452
389 id = register_ftrace_event(call->event); 453 id = register_ftrace_event(call->event);
390 if (!id) 454 if (!id) {
455 free_syscall_print_fmt(call);
391 return -ENODEV; 456 return -ENODEV;
457 }
392 call->id = id; 458 call->id = id;
393 INIT_LIST_HEAD(&call->fields); 459 INIT_LIST_HEAD(&call->fields);
394 return 0; 460 return 0;