2 * ring buffer based initcalls tracer
4 * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
8 #include <linux/init.h>
9 #include <linux/debugfs.h>
10 #include <linux/ftrace.h>
14 static struct trace_array
*boot_trace
;
15 static int trace_boot_enabled
;
18 /* Should be started after do_pre_smp_initcalls() in init/main.c */
19 void start_boot_trace(void)
21 trace_boot_enabled
= 1;
24 void stop_boot_trace(struct trace_array
*tr
)
26 trace_boot_enabled
= 0;
29 static void boot_trace_init(struct trace_array
*tr
)
34 trace_boot_enabled
= 0;
36 for_each_cpu_mask(cpu
, cpu_possible_map
)
37 tracing_reset(tr
, cpu
);
40 static void boot_trace_ctrl_update(struct trace_array
*tr
)
48 static int initcall_print_line(struct trace_iterator
*iter
)
51 struct trace_entry
*entry
= iter
->ent
;
52 struct trace_boot
*field
= (struct trace_boot
*)entry
;
53 struct boot_trace
*it
= &field
->initcall
;
54 struct trace_seq
*s
= &iter
->seq
;
56 if (entry
->type
== TRACE_BOOT
)
57 ret
= trace_seq_printf(s
, "%pF called from %i "
58 "returned %d after %lld msecs\n",
59 it
->func
, it
->caller
, it
->result
,
66 struct tracer boot_tracer __read_mostly
=
69 .init
= boot_trace_init
,
70 .reset
= stop_boot_trace
,
71 .ctrl_update
= boot_trace_ctrl_update
,
72 .print_line
= initcall_print_line
,
76 void trace_boot(struct boot_trace
*it
)
78 struct ring_buffer_event
*event
;
79 struct trace_boot
*entry
;
80 struct trace_array_cpu
*data
;
81 unsigned long irq_flags
;
82 struct trace_array
*tr
= boot_trace
;
84 if (!trace_boot_enabled
)
88 data
= tr
->data
[smp_processor_id()];
90 event
= ring_buffer_lock_reserve(tr
->buffer
, sizeof(*entry
),
94 entry
= ring_buffer_event_data(event
);
95 tracing_generic_entry_update(&entry
->ent
, 0);
96 entry
->ent
.type
= TRACE_BOOT
;
97 entry
->initcall
= *it
;
98 ring_buffer_unlock_commit(tr
->buffer
, event
, irq_flags
);