aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ftrace.h24
-rw-r--r--init/main.c4
-rw-r--r--kernel/trace/trace_boot.c28
3 files changed, 41 insertions, 15 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index e46a7b34037c..4642959e5bda 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -234,6 +234,11 @@ ftrace_init_module(unsigned long *start, unsigned long *end) { }
234#endif 234#endif
235 235
236 236
237/*
238 * Structure which defines the trace of an initcall.
239 * You don't have to fill the func field since it is
240 * only used internally by the tracer.
241 */
237struct boot_trace { 242struct boot_trace {
238 pid_t caller; 243 pid_t caller;
239 char func[KSYM_NAME_LEN]; 244 char func[KSYM_NAME_LEN];
@@ -244,13 +249,28 @@ struct boot_trace {
244}; 249};
245 250
246#ifdef CONFIG_BOOT_TRACER 251#ifdef CONFIG_BOOT_TRACER
252/* Append the trace on the ring-buffer */
247extern void trace_boot(struct boot_trace *it, initcall_t fn); 253extern void trace_boot(struct boot_trace *it, initcall_t fn);
254
255/* Tells the tracer that smp_pre_initcall is finished.
256 * So we can start the tracing
257 */
248extern void start_boot_trace(void); 258extern void start_boot_trace(void);
249extern void stop_boot_trace(void); 259
260/* Resume the tracing of other necessary events
261 * such as sched switches
262 */
263extern void enable_boot_trace(void);
264
265/* Suspend this tracing. Actually, only sched_switches tracing have
266 * to be suspended. Initcalls doesn't need it.)
267 */
268extern void disable_boot_trace(void);
250#else 269#else
251static inline void trace_boot(struct boot_trace *it, initcall_t fn) { } 270static inline void trace_boot(struct boot_trace *it, initcall_t fn) { }
252static inline void start_boot_trace(void) { } 271static inline void start_boot_trace(void) { }
253static inline void stop_boot_trace(void) { } 272static inline void enable_boot_trace(void) { }
273static inline void disable_boot_trace(void) { }
254#endif 274#endif
255 275
256 276
diff --git a/init/main.c b/init/main.c
index 7e117a231af1..4b03cd5656ca 100644
--- a/init/main.c
+++ b/init/main.c
@@ -711,6 +711,7 @@ int do_one_initcall(initcall_t fn)
711 it.caller = task_pid_nr(current); 711 it.caller = task_pid_nr(current);
712 printk("calling %pF @ %i\n", fn, it.caller); 712 printk("calling %pF @ %i\n", fn, it.caller);
713 it.calltime = ktime_get(); 713 it.calltime = ktime_get();
714 enable_boot_trace();
714 } 715 }
715 716
716 it.result = fn(); 717 it.result = fn();
@@ -722,6 +723,7 @@ int do_one_initcall(initcall_t fn)
722 printk("initcall %pF returned %d after %Ld usecs\n", fn, 723 printk("initcall %pF returned %d after %Ld usecs\n", fn,
723 it.result, it.duration); 724 it.result, it.duration);
724 trace_boot(&it, fn); 725 trace_boot(&it, fn);
726 disable_boot_trace();
725 } 727 }
726 728
727 msgbuf[0] = 0; 729 msgbuf[0] = 0;
@@ -882,7 +884,7 @@ static int __init kernel_init(void * unused)
882 * we're essentially up and running. Get rid of the 884 * we're essentially up and running. Get rid of the
883 * initmem segments and start the user-mode stuff.. 885 * initmem segments and start the user-mode stuff..
884 */ 886 */
885 stop_boot_trace(); 887
886 init_post(); 888 init_post();
887 return 0; 889 return 0;
888} 890}
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
index d0a5e50eeff2..d104d5b46413 100644
--- a/kernel/trace/trace_boot.c
+++ b/kernel/trace/trace_boot.c
@@ -13,23 +13,29 @@
13#include "trace.h" 13#include "trace.h"
14 14
15static struct trace_array *boot_trace; 15static struct trace_array *boot_trace;
16static int trace_boot_enabled; 16static bool pre_initcalls_finished;
17 17
18 18/* Tells the boot tracer that the pre_smp_initcalls are finished.
19/* Should be started after do_pre_smp_initcalls() in init/main.c */ 19 * So we are ready .
20 * It doesn't enable sched events tracing however.
21 * You have to call enable_boot_trace to do so.
22 */
20void start_boot_trace(void) 23void start_boot_trace(void)
21{ 24{
22 trace_boot_enabled = 1; 25 pre_initcalls_finished = true;
26}
27
28void enable_boot_trace(void)
29{
23} 30}
24 31
25void stop_boot_trace(void) 32void disable_boot_trace(void)
26{ 33{
27 trace_boot_enabled = 0;
28} 34}
29 35
30void reset_boot_trace(struct trace_array *tr) 36void reset_boot_trace(struct trace_array *tr)
31{ 37{
32 stop_boot_trace(); 38 disable_boot_trace();
33} 39}
34 40
35static void boot_trace_init(struct trace_array *tr) 41static void boot_trace_init(struct trace_array *tr)
@@ -37,8 +43,6 @@ static void boot_trace_init(struct trace_array *tr)
37 int cpu; 43 int cpu;
38 boot_trace = tr; 44 boot_trace = tr;
39 45
40 trace_boot_enabled = 0;
41
42 for_each_cpu_mask(cpu, cpu_possible_map) 46 for_each_cpu_mask(cpu, cpu_possible_map)
43 tracing_reset(tr, cpu); 47 tracing_reset(tr, cpu);
44} 48}
@@ -46,9 +50,9 @@ static void boot_trace_init(struct trace_array *tr)
46static void boot_trace_ctrl_update(struct trace_array *tr) 50static void boot_trace_ctrl_update(struct trace_array *tr)
47{ 51{
48 if (tr->ctrl) 52 if (tr->ctrl)
49 start_boot_trace(); 53 enable_boot_trace();
50 else 54 else
51 stop_boot_trace(); 55 disable_boot_trace();
52} 56}
53 57
54static enum print_line_t initcall_print_line(struct trace_iterator *iter) 58static enum print_line_t initcall_print_line(struct trace_iterator *iter)
@@ -99,7 +103,7 @@ void trace_boot(struct boot_trace *it, initcall_t fn)
99 unsigned long irq_flags; 103 unsigned long irq_flags;
100 struct trace_array *tr = boot_trace; 104 struct trace_array *tr = boot_trace;
101 105
102 if (!trace_boot_enabled) 106 if (!pre_initcalls_finished)
103 return; 107 return;
104 108
105 /* Get its name now since this function could 109 /* Get its name now since this function could