diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2008-10-31 07:57:20 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-04 11:14:02 -0500 |
commit | 71566a0d161edec70361b7f90f6e54af6a6d5d05 (patch) | |
tree | 78d2d790ed4e20c179d2f61f2ed50ecbb6d5a451 | |
parent | 7a895f53cda9d9362c30144e42c124a1ae996b9e (diff) |
tracing/fastboot: Enable boot tracing only during initcalls
Impact: modify boot tracer
We used to disable the initcall tracing at a specified time (IE: end
of builtin initcalls). But we don't need it anymore. It will be
stopped when initcalls are finished.
However we want two things:
_Start this tracing only after pre-smp initcalls are finished.
_Since we are planning to trace sched_switches at the same time, we
want to enable them only during the initcall execution.
For this purpose, this patch introduce two functions to enable/disable
the sched_switch tracing during boot.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | include/linux/ftrace.h | 24 | ||||
-rw-r--r-- | init/main.c | 4 | ||||
-rw-r--r-- | kernel/trace/trace_boot.c | 28 |
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 | */ | ||
237 | struct boot_trace { | 242 | struct 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 */ | ||
247 | extern void trace_boot(struct boot_trace *it, initcall_t fn); | 253 | extern 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 | */ | ||
248 | extern void start_boot_trace(void); | 258 | extern void start_boot_trace(void); |
249 | extern void stop_boot_trace(void); | 259 | |
260 | /* Resume the tracing of other necessary events | ||
261 | * such as sched switches | ||
262 | */ | ||
263 | extern 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 | */ | ||
268 | extern void disable_boot_trace(void); | ||
250 | #else | 269 | #else |
251 | static inline void trace_boot(struct boot_trace *it, initcall_t fn) { } | 270 | static inline void trace_boot(struct boot_trace *it, initcall_t fn) { } |
252 | static inline void start_boot_trace(void) { } | 271 | static inline void start_boot_trace(void) { } |
253 | static inline void stop_boot_trace(void) { } | 272 | static inline void enable_boot_trace(void) { } |
273 | static 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 | ||
15 | static struct trace_array *boot_trace; | 15 | static struct trace_array *boot_trace; |
16 | static int trace_boot_enabled; | 16 | static 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 | */ | ||
20 | void start_boot_trace(void) | 23 | void start_boot_trace(void) |
21 | { | 24 | { |
22 | trace_boot_enabled = 1; | 25 | pre_initcalls_finished = true; |
26 | } | ||
27 | |||
28 | void enable_boot_trace(void) | ||
29 | { | ||
23 | } | 30 | } |
24 | 31 | ||
25 | void stop_boot_trace(void) | 32 | void disable_boot_trace(void) |
26 | { | 33 | { |
27 | trace_boot_enabled = 0; | ||
28 | } | 34 | } |
29 | 35 | ||
30 | void reset_boot_trace(struct trace_array *tr) | 36 | void reset_boot_trace(struct trace_array *tr) |
31 | { | 37 | { |
32 | stop_boot_trace(); | 38 | disable_boot_trace(); |
33 | } | 39 | } |
34 | 40 | ||
35 | static void boot_trace_init(struct trace_array *tr) | 41 | static 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) | |||
46 | static void boot_trace_ctrl_update(struct trace_array *tr) | 50 | static 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 | ||
54 | static enum print_line_t initcall_print_line(struct trace_iterator *iter) | 58 | static 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 |