Browse Source

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>
Frederic Weisbecker 16 years ago
parent
commit
71566a0d16
3 changed files with 41 additions and 15 deletions
  1. 22 2
      include/linux/ftrace.h
  2. 3 1
      init/main.c
  3. 16 12
      kernel/trace/trace_boot.c

+ 22 - 2
include/linux/ftrace.h

@@ -234,6 +234,11 @@ ftrace_init_module(unsigned long *start, unsigned long *end) { }
 #endif
 #endif
 
 
 
 
+/*
+ * Structure which defines the trace of an initcall.
+ * You don't have to fill the func field since it is
+ * only used internally by the tracer.
+ */
 struct boot_trace {
 struct boot_trace {
 	pid_t			caller;
 	pid_t			caller;
 	char			func[KSYM_NAME_LEN];
 	char			func[KSYM_NAME_LEN];
@@ -244,13 +249,28 @@ struct boot_trace {
 };
 };
 
 
 #ifdef CONFIG_BOOT_TRACER
 #ifdef CONFIG_BOOT_TRACER
+/* Append the trace on the ring-buffer */
 extern void trace_boot(struct boot_trace *it, initcall_t fn);
 extern void trace_boot(struct boot_trace *it, initcall_t fn);
+
+/* Tells the tracer that smp_pre_initcall is finished.
+ * So we can start the tracing
+ */
 extern void start_boot_trace(void);
 extern void start_boot_trace(void);
-extern void stop_boot_trace(void);
+
+/* Resume the tracing of other necessary events
+ * such as sched switches
+ */
+extern void enable_boot_trace(void);
+
+/* Suspend this tracing. Actually, only sched_switches tracing have
+ * to be suspended. Initcalls doesn't need it.)
+ */
+extern void disable_boot_trace(void);
 #else
 #else
 static inline void trace_boot(struct boot_trace *it, initcall_t fn) { }
 static inline void trace_boot(struct boot_trace *it, initcall_t fn) { }
 static inline void start_boot_trace(void) { }
 static inline void start_boot_trace(void) { }
-static inline void stop_boot_trace(void) { }
+static inline void enable_boot_trace(void) { }
+static inline void disable_boot_trace(void) { }
 #endif
 #endif
 
 
 
 

+ 3 - 1
init/main.c

@@ -711,6 +711,7 @@ int do_one_initcall(initcall_t fn)
 		it.caller = task_pid_nr(current);
 		it.caller = task_pid_nr(current);
 		printk("calling  %pF @ %i\n", fn, it.caller);
 		printk("calling  %pF @ %i\n", fn, it.caller);
 		it.calltime = ktime_get();
 		it.calltime = ktime_get();
+		enable_boot_trace();
 	}
 	}
 
 
 	it.result = fn();
 	it.result = fn();
@@ -722,6 +723,7 @@ int do_one_initcall(initcall_t fn)
 		printk("initcall %pF returned %d after %Ld usecs\n", fn,
 		printk("initcall %pF returned %d after %Ld usecs\n", fn,
 			it.result, it.duration);
 			it.result, it.duration);
 		trace_boot(&it, fn);
 		trace_boot(&it, fn);
+		disable_boot_trace();
 	}
 	}
 
 
 	msgbuf[0] = 0;
 	msgbuf[0] = 0;
@@ -882,7 +884,7 @@ static int __init kernel_init(void * unused)
 	 * we're essentially up and running. Get rid of the
 	 * we're essentially up and running. Get rid of the
 	 * initmem segments and start the user-mode stuff..
 	 * initmem segments and start the user-mode stuff..
 	 */
 	 */
-	stop_boot_trace();
+
 	init_post();
 	init_post();
 	return 0;
 	return 0;
 }
 }

+ 16 - 12
kernel/trace/trace_boot.c

@@ -13,23 +13,29 @@
 #include "trace.h"
 #include "trace.h"
 
 
 static struct trace_array *boot_trace;
 static struct trace_array *boot_trace;
-static int trace_boot_enabled;
+static bool pre_initcalls_finished;
 
 
-
-/* Should be started after do_pre_smp_initcalls() in init/main.c */
+/* Tells the boot tracer that the pre_smp_initcalls are finished.
+ * So we are ready .
+ * It doesn't enable sched events tracing however.
+ * You have to call enable_boot_trace to do so.
+ */
 void start_boot_trace(void)
 void start_boot_trace(void)
 {
 {
-	trace_boot_enabled = 1;
+	pre_initcalls_finished = true;
+}
+
+void enable_boot_trace(void)
+{
 }
 }
 
 
-void stop_boot_trace(void)
+void disable_boot_trace(void)
 {
 {
-	trace_boot_enabled = 0;
 }
 }
 
 
 void reset_boot_trace(struct trace_array *tr)
 void reset_boot_trace(struct trace_array *tr)
 {
 {
-	stop_boot_trace();
+	disable_boot_trace();
 }
 }
 
 
 static void boot_trace_init(struct trace_array *tr)
 static void boot_trace_init(struct trace_array *tr)
@@ -37,8 +43,6 @@ static void boot_trace_init(struct trace_array *tr)
 	int cpu;
 	int cpu;
 	boot_trace = tr;
 	boot_trace = tr;
 
 
-	trace_boot_enabled = 0;
-
 	for_each_cpu_mask(cpu, cpu_possible_map)
 	for_each_cpu_mask(cpu, cpu_possible_map)
 		tracing_reset(tr, cpu);
 		tracing_reset(tr, cpu);
 }
 }
@@ -46,9 +50,9 @@ static void boot_trace_init(struct trace_array *tr)
 static void boot_trace_ctrl_update(struct trace_array *tr)
 static void boot_trace_ctrl_update(struct trace_array *tr)
 {
 {
 	if (tr->ctrl)
 	if (tr->ctrl)
-		start_boot_trace();
+		enable_boot_trace();
 	else
 	else
-		stop_boot_trace();
+		disable_boot_trace();
 }
 }
 
 
 static enum print_line_t initcall_print_line(struct trace_iterator *iter)
 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)
 	unsigned long irq_flags;
 	unsigned long irq_flags;
 	struct trace_array *tr = boot_trace;
 	struct trace_array *tr = boot_trace;
 
 
-	if (!trace_boot_enabled)
+	if (!pre_initcalls_finished)
 		return;
 		return;
 
 
 	/* Get its name now since this function could
 	/* Get its name now since this function could