perf s390: Move syscall.tbl check into check-headers.sh
[linux-2.6-microblaze.git] / kernel / trace / trace.c
index 410cfeb..b8a2d78 100644 (file)
@@ -68,10 +68,21 @@ bool ring_buffer_expanded;
 static bool __read_mostly tracing_selftest_running;
 
 /*
- * If a tracer is running, we do not want to run SELFTEST.
+ * If boot-time tracing including tracers/events via kernel cmdline
+ * is running, we do not want to run SELFTEST.
  */
 bool __read_mostly tracing_selftest_disabled;
 
+#ifdef CONFIG_FTRACE_STARTUP_TEST
+void __init disable_tracing_selftest(const char *reason)
+{
+       if (!tracing_selftest_disabled) {
+               tracing_selftest_disabled = true;
+               pr_info("Ftrace startup test is disabled due to %s\n", reason);
+       }
+}
+#endif
+
 /* Pipe tracepoints to printk */
 struct trace_iterator *tracepoint_print_iter;
 int tracepoint_printk;
@@ -163,7 +174,8 @@ static union trace_eval_map_item *trace_eval_maps;
 #endif /* CONFIG_TRACE_EVAL_MAP_FILE */
 
 int tracing_set_tracer(struct trace_array *tr, const char *buf);
-static void ftrace_trace_userstack(struct trace_buffer *buffer,
+static void ftrace_trace_userstack(struct trace_array *tr,
+                                  struct trace_buffer *buffer,
                                   unsigned long flags, int pc);
 
 #define MAX_TRACER_SIZE                100
@@ -2112,11 +2124,7 @@ int __init register_tracer(struct tracer *type)
        apply_trace_boot_options();
 
        /* disable other selftests, since this will break it. */
-       tracing_selftest_disabled = true;
-#ifdef CONFIG_FTRACE_STARTUP_TEST
-       printk(KERN_INFO "Disabling FTRACE selftests due to running tracer '%s'\n",
-              type->name);
-#endif
+       disable_tracing_selftest("running a tracer");
 
  out_unlock:
        return ret;
@@ -2870,7 +2878,7 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
         * two. They are not that meaningful.
         */
        ftrace_trace_stack(tr, buffer, flags, regs ? 0 : STACK_SKIP, pc, regs);
-       ftrace_trace_userstack(buffer, flags, pc);
+       ftrace_trace_userstack(tr, buffer, flags, pc);
 }
 
 /*
@@ -3056,13 +3064,14 @@ EXPORT_SYMBOL_GPL(trace_dump_stack);
 static DEFINE_PER_CPU(int, user_stack_count);
 
 static void
-ftrace_trace_userstack(struct trace_buffer *buffer, unsigned long flags, int pc)
+ftrace_trace_userstack(struct trace_array *tr,
+                      struct trace_buffer *buffer, unsigned long flags, int pc)
 {
        struct trace_event_call *call = &event_user_stack;
        struct ring_buffer_event *event;
        struct userstack_entry *entry;
 
-       if (!(global_trace.trace_flags & TRACE_ITER_USERSTACKTRACE))
+       if (!(tr->trace_flags & TRACE_ITER_USERSTACKTRACE))
                return;
 
        /*
@@ -3101,7 +3110,8 @@ ftrace_trace_userstack(struct trace_buffer *buffer, unsigned long flags, int pc)
        preempt_enable();
 }
 #else /* CONFIG_USER_STACKTRACE_SUPPORT */
-static void ftrace_trace_userstack(struct trace_buffer *buffer,
+static void ftrace_trace_userstack(struct trace_array *tr,
+                                  struct trace_buffer *buffer,
                                   unsigned long flags, int pc)
 {
 }
@@ -3118,7 +3128,7 @@ struct trace_buffer_struct {
 static struct trace_buffer_struct *trace_percpu_buffer;
 
 /*
- * Thise allows for lockless recording.  If we're nested too deeply, then
+ * This allows for lockless recording.  If we're nested too deeply, then
  * this returns NULL.
  */
 static char *get_trace_buf(void)
@@ -3534,7 +3544,7 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu,
 }
 
 #define STATIC_TEMP_BUF_SIZE   128
-static char static_temp_buf[STATIC_TEMP_BUF_SIZE];
+static char static_temp_buf[STATIC_TEMP_BUF_SIZE] __aligned(4);
 
 /* Find the next real entry, without updating the iterator itself */
 struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
@@ -9059,7 +9069,10 @@ int tracing_init_dentry(void)
 extern struct trace_eval_map *__start_ftrace_eval_maps[];
 extern struct trace_eval_map *__stop_ftrace_eval_maps[];
 
-static void __init trace_eval_init(void)
+static struct workqueue_struct *eval_map_wq __initdata;
+static struct work_struct eval_map_work __initdata;
+
+static void __init eval_map_work_func(struct work_struct *work)
 {
        int len;
 
@@ -9067,6 +9080,33 @@ static void __init trace_eval_init(void)
        trace_insert_eval_map(NULL, __start_ftrace_eval_maps, len);
 }
 
+static int __init trace_eval_init(void)
+{
+       INIT_WORK(&eval_map_work, eval_map_work_func);
+
+       eval_map_wq = alloc_workqueue("eval_map_wq", WQ_UNBOUND, 0);
+       if (!eval_map_wq) {
+               pr_err("Unable to allocate eval_map_wq\n");
+               /* Do work here */
+               eval_map_work_func(&eval_map_work);
+               return -ENOMEM;
+       }
+
+       queue_work(eval_map_wq, &eval_map_work);
+       return 0;
+}
+
+static int __init trace_eval_sync(void)
+{
+       /* Make sure the eval map updates are finished */
+       if (eval_map_wq)
+               destroy_workqueue(eval_map_wq);
+       return 0;
+}
+
+late_initcall_sync(trace_eval_sync);
+
+
 #ifdef CONFIG_MODULES
 static void trace_module_add_evals(struct module *mod)
 {